(EDITED: Saved some lines, 382 line)
Code: Select all
; Copyright 2007 ChipEm Revised by Pedro Gil (Balrog Soft)
InitSprite()
InitKeyboard()
Global *MEM, *RAM.Character, DT, ST
Procedure counters()
If (DT > 0) : DT - 1 : EndIf
If (ST > 0) : ST - 1 : EndIf
If (DT < 0) : DT = 0 : EndIf
If (ST < 0) : ST = 0 : EndIf
EndProcedure
Procedure GetPC()
ProcedureReturn *RAM - *MEM
EndProcedure
Dim subAddress.w(15)
Dim V.c(15)
Dim Key.b(15)
Dim KeyCode(15)
KeyCode(0) = #PB_Key_X
KeyCode(1) = #PB_Key_1
KeyCode(2) = #PB_Key_2
KeyCode(3) = #PB_Key_3
KeyCode(4) = #PB_Key_Q
KeyCode(5) = #PB_Key_W
KeyCode(6) = #PB_Key_E
KeyCode(7) = #PB_Key_A
KeyCode(8) = #PB_Key_S
KeyCode(9) = #PB_Key_D
KeyCode(10) = #PB_Key_Z
KeyCode(11) = #PB_Key_C
KeyCode(12) = #PB_Key_4
KeyCode(13) = #PB_Key_R
KeyCode(14) = #PB_Key_F
KeyCode(15) = #PB_Key_V
*MEM = AllocateMemory(4096)
*RAM.Character = *MEM
File.s = OpenFileRequester("Open Chip 8 ROM", "", "", 0)
If File.s
If ReadFile(0, File.s)
ReadData(0, *MEM + $200, Lof(0))
CloseFile(0)
EndIf
Else
FreeMemory(*MEM)
End
EndIf
If OpenWindow(0, 100, 100, 256, 128, "ChipEm rEvISeD", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 256, 128, 0, 0, 0)
CreateImage(0, 64, 32, #PB_Image_DisplayFormat)
Skip.b = #False
Jump.b = #False
flipScreen.b = #False
EmulationActive.b = #True
WaitKey.b = #False
SP = 0 : DT = 0 : ST = 0 : Index = 0
Restore FontData
For i = 0 To 79
Read b.c
*RAM\c = b.c
*RAM + 1
Next i
*RAM = *MEM + $200
timer = GetTickCount_()
Repeat
If EmulationActive.b = #True
WindowEvent = WindowEvent()
ElseIf EmulationActive.b = #False
WindowEvent = WaitWindowEvent()
EndIf
If WindowEvent = #PB_Event_CloseWindow
Quit = #True
EndIf
If EmulationActive.b = #True
ExamineKeyboard()
For k = 0 To 15
Key(k) = #False
If KeyboardPushed(KeyCode(k))
Key(k) = #True
EndIf
Next
If WaitKey = #False
If GetTickCount_() - timer >= 16
counters()
timer = GetTickCount_()
EndIf
Skip.b = #False
Jump.b = #False
flipScreen.b = #False
OpCode.c = *RAM\c
OpCodeH.c = (OpCode >> 4) & $f
OpCodeL.c = OpCode & $f
*ptr.Character = *RAM + 1
HByte.c = *ptr\c
Select OpCodeH
Case $0:
Select HByte
Case $e0:
CreateImage(0, 64, 32, #PB_Image_DisplayFormat)
Case $ee:
SP - 1
*RAM = *MEM + (subAddress(SP) + 2)
Jump = #True
EndSelect
Case $1:
*RAM = *MEM + ((OpCodeL << 8) + HByte)
Jump = #True
Case $2:
subAddress(SP) = GetPC()
SP + 1
*RAM = *MEM + ((OpCodeL << 8) + HByte)
Jump = #True
Case $3:
If (V(OpCodeL) = HByte)
Skip = #True
Else
Skip = #False
EndIf
Case $4:
If (V(OpCodeL) <> HByte)
Skip = #True
Else
Skip = #False
EndIf
Case $5:
reg = (HByte >> 4) & $f
If (V(OpCodeL) = V(reg))
Skip = #True
Else
Skip = #False
EndIf
Case $6:
V(OpCodeL) = HByte
Case $7:
V(OpCodeL) + HByte
Case $8:
Operator = HByte & $f
reg = (HByte >> 4) & $f
Select Operator
Case $0:
V(OpCodeL) = V(reg)
Case $1:
V(OpCodeL) | V(reg)
Case $2:
V(OpCodeL) & V(reg)
Case $3:
V(OpCodeL) ! V(reg)
Case $4:
V($f) = ((V(OpCodeL) + V(reg)) >> 8) & 1
V(OpCodeL) + V(reg)
Case $5:
V($0f) = ((((V(OpCodeL) - V(reg)) >> 8) + 1) & 1)
V(OpCodeL) - V(reg)
Case $6:
V($f) = V(OpCodeL) & 1
V(OpCodeL) = V(OpCodeL) >> 1
Case $7:
V($0f) = ((((V(reg) - V(OpCodeL)) >> 8) + 1) & 1)
V(OpCodeL) = V(reg) - V(OpCodeL)
Case $e:
V($f) = (V(OpCodeL) >> 7) & 1
V(OpCodeL) = V(OpCodeL) << 1
EndSelect
Case $9:
If (V(OpCodeL) <> V((HByte >> 4) & $f))
Skip = #True
Else
Skip = #False
EndIf
Case $a:
Index = (OpCodeL << 8) + HByte
Case $b:
*RAM = *MEM + ((OpCodeL << 8) + HByte + V($0))
Jump = #True
Case $c:
V(OpCodeL) = Random(HByte)
Case $d:
height = HByte & $f
reg = (HByte >> 4) & $f
sprx = V(OpCodeL)
spry = V(reg)
V($f) = 0
*ptr.Character = *MEM
*ptr + Index
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_XOr)
For y = 0 To height - 1
For x = 0 To 7
xc = (x + sprx) % 64
yc = (y + spry) % 32
Pixel = (*ptr\c >> (7 - x)) & $1
If Pixel
prev = Point(xc, yc)
Plot(xc, yc, $FFFFFF)
If prev <> 0 : V($f) = 1 : EndIf
If prev = 0 And flipScreen = #False
flipScreen = #True
EndIf
EndIf
Next x
*ptr + 1
Next y
StopDrawing()
Case $e:
Select HByte
Case $9e:
If (Key(V(OpCodeL)) = #True)
Skip = #True
EndIf
Case $a1:
If (Key(V(OpCodeL)) <> #True)
Skip = #True
EndIf
EndSelect
Case $f:
Select HByte
Case $07:
V(OpCodeL) = DT
Case $0a:
WaitKey = #True
registerKey = OpCodeL
Case $15:
DT = V(OpCodeL)
Case $18:
ST = V(OpCodeL)
Case $1e:
Index + V(OpCodeL)
Case $29:
Index = (5 * V(OpCodeL))
Case $33:
bcd.s = Str(V(OpCodeL))
If (Len(bcd) = 1)
bcd = "00" + bcd
ElseIf (Len(bcd) = 2)
bcd = "0" + bcd
EndIf
*ptr.Character = *MEM
*ptr + Index
*ptr\c = Val(Mid(bcd, 1, 1))
*ptr + 1
*ptr\c = Val(Mid(bcd, 2, 1))
*ptr + 1
*ptr\c = Val(Mid(bcd, 3, 1))
Case $55:
*ptr.Character = *MEM
*ptr + Index
For reg = 0 To OpCodeL
*ptr\c = V(reg)
*ptr + 1
Next reg
Case $65:
*ptr.Character = *MEM
*ptr + Index
For reg = 0 To OpCodeL
V(reg) = *ptr\c
*ptr + 1
Next reg
EndSelect
EndSelect
If Jump = #False
If Skip = #False
*RAM + 2
Else
*RAM + 4
EndIf
EndIf
If FlipScreen = #True
CopyImage(0, 1)
ResizeImage(1, 256, 128, #PB_Image_Raw)
StartDrawing(ScreenOutput())
DrawImage(ImageID(1), 0, 0)
StopDrawing()
FlipBuffers()
EndIf
EndIf
EndIf
If WaitKey = #True
For reg = 0 To 15
If Key(reg) = #True
V(registerKey) = reg
WaitKey = #False
EndIf
Next reg
EndIf
Until Quit = #True
CloseWindow(0)
EndIf
FreeMemory(*MEM)
End
DataSection
FontData:
Data.b $F0, $90, $90, $90, $F0
Data.b $20, $60, $20, $20, $70
Data.b $F0, $10, $F0, $80, $F0
Data.b $F0, $10, $F0, $10, $F0
Data.b $90, $90, $F0, $10, $10
Data.b $F0, $80, $F0, $10, $F0
Data.b $F0, $80, $F0, $90, $F0
Data.b $F0, $10, $20, $40, $40
Data.b $F0, $90, $F0, $90, $F0
Data.b $F0, $90, $F0, $10, $F0
Data.b $F0, $90, $F0, $90, $90
Data.b $E0, $90, $E0, $90, $E0
Data.b $F0, $80, $80, $80, $F0
Data.b $E0, $90, $90, $90, $E0
Data.b $F0, $80, $F0, $80, $F0
Data.b $F0, $80, $F0, $80, $80
EndDataSection