mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-09-29 06:55:37 +00:00
astrocade: updated bios
This commit is contained in:
parent
92170dd5c4
commit
53d6dce4de
383
presets/astrocade-bios/astrocade.inc
Normal file
383
presets/astrocade-bios/astrocade.inc
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
|
||||||
|
; ****** HVGLIB.H (formally called ballyequ.h) (C)1977,78
|
||||||
|
; *** Bally Astrocade Equates and Macros Header File ***
|
||||||
|
; From the nutting_manual and reformatted using Mixed Case
|
||||||
|
; Version 3.01 - thru December 29, 2010
|
||||||
|
; by Richard C Degler, from scratch
|
||||||
|
;
|
||||||
|
; > Retyped and proofread by Adam Trionfo and Lance F. Squire
|
||||||
|
; > Version 1.0 (as ballyequ.h) - January 17, 2002
|
||||||
|
; > Version 2.52 (Version 1.0 of HVGLIB.H) - March 28, 2003
|
||||||
|
; > Version 2.6 - March 2, 2004 - as seen on BallyAlley.com
|
||||||
|
; > Version 3.0 - 2009
|
||||||
|
; > Version 3.01 - Changed "FonT BASE character" comment
|
||||||
|
;
|
||||||
|
; ***************************
|
||||||
|
; * Home Video Game =ates *
|
||||||
|
; ***************************
|
||||||
|
;
|
||||||
|
; ASSEMBLY CONTROL
|
||||||
|
;
|
||||||
|
XPNDON = 1 ; ** SET TO 1 WHEN HARDWARE EXP
|
||||||
|
NWHDWR = 1 ; ** SET TO 1 WHEN NEW HARDWARE
|
||||||
|
;
|
||||||
|
; General goodies (HEX and Decimal values):
|
||||||
|
NORMEM = 0x4000 ; 8192 ; NORmal MEMory start
|
||||||
|
FIRSTC = 0x2000 ; 4096 ; FIRST address in Cartridge
|
||||||
|
SCREEN = 0x0000 ; 0 ; magic SCREEN start
|
||||||
|
BYTEPL = 0x28 ; 40 ; BYTEs Per Line
|
||||||
|
BITSPL = 0xA0 ; 160 ; BITS Per Line
|
||||||
|
;
|
||||||
|
; Stuff in SYSTEM DOPE VECTOR (valid for ALL system ROMs):
|
||||||
|
STIMER = 0x0200 ; Seconds and game TIMER, music
|
||||||
|
CTIMER = 0x0203 ; Custom TIMERs
|
||||||
|
FNTSYS = 0x0206 ; FoNT descriptor for SYStem font
|
||||||
|
FNTSML = 0x020D ; FoNT descriptor for SMaLl font
|
||||||
|
ALKEYS = 0x0214 ; ALl KEYS keypad mask
|
||||||
|
MENUST = 0x0218 ; head of onboard MENU STart
|
||||||
|
MXSCR = 0x021E ; address of 'MaX SCoRe' text string
|
||||||
|
NOPLAY = 0x0228 ; address of 'Number Of PLAYers' string
|
||||||
|
NOGAME = 0x0235 ; address of 'Number Of GAMEs' string
|
||||||
|
;
|
||||||
|
; BITS in PROCESSOR FLAG byte:
|
||||||
|
PSWCY = 0 ; Processor Status Word, CarrY bit
|
||||||
|
PSWPV = 2 ; Processor Status Word, Parity or oVerflow bit
|
||||||
|
PSWZRO = 6 ; Processor Status Word, ZeRO bit
|
||||||
|
PSWSGN = 7 ; Processor Status Word, SiGN bit
|
||||||
|
;
|
||||||
|
; BITS in GAME STATUS Byte:
|
||||||
|
GSBTIM = 0 ; Game Status Byte, if TIMe is up set end bit
|
||||||
|
GSBSCR = 1 ; Game Status Byte, if SCoRe reached set end bit
|
||||||
|
GSBEND = 7 ; Game Status Byte, END flag bit
|
||||||
|
;
|
||||||
|
; Standard VECTOR DISPLACEMENTS and bits:
|
||||||
|
VBMR = 0x00 ; +0 ; Vector Block, Magic Register
|
||||||
|
VBSTAT = 0x01 ; +1 ; Vector Block, STATus byte
|
||||||
|
VBTIMB = 0x02 ; +2 ; Vector Block, TIMe Base
|
||||||
|
VBDXL = 0x03 ; +3 ; Vector Block, Delta for X Low
|
||||||
|
VBDXH = 0x04 ; +4 ; Vector Block, Delta for X Hi
|
||||||
|
VBXL = 0x05 ; +5 ; Vector Block, X coord Low
|
||||||
|
VBXH = 0x06 ; +6 ; Vector Block, X coord Hi
|
||||||
|
VBXCHK = 0x07 ; +7 ; Vector Block, X CHecK flags
|
||||||
|
VBDYL = 0x08 ; +8 ; Vector Block, Delta for Y Low
|
||||||
|
VBDYH = 0x09 ; +9 ; Vector Block, Delta for Y Hi
|
||||||
|
VBYL = 0x0A ; +10 ; Vector Block, Y coord Low
|
||||||
|
VBYH = 0x0B ; +11 ; Vector Block, Y coord Hi
|
||||||
|
VBYCHK = 0x0C ; +12 ; Vector Block, Y CHecK flags
|
||||||
|
VBOAL = 0x0D ; +13 ; Vector Block, Old Address Low
|
||||||
|
VBOAH = 0x0E ; +14 ; Vector Block, Old Address Hi
|
||||||
|
;
|
||||||
|
; DISPLACEMENTS from start of COORDINATE AREA (X or Y):
|
||||||
|
VBDCL = 0x00 ; +0 ; Vector Block, Delta for Coord Low
|
||||||
|
VBDCH = 0x01 ; +1 ; Vector Block, Delta for Coord Hi
|
||||||
|
VBCL = 0x02 ; +2 ; Vector Block, Coord Low
|
||||||
|
VBCH = 0x03 ; +3 ; Vector Block, Coord Hi
|
||||||
|
VBCCHK = 0x04 ; +4 ; Vector Block, Coord CHecK flags
|
||||||
|
;
|
||||||
|
; BITS in STATUS byte:
|
||||||
|
VBBLNK = 6 ; Vector Block status, BLaNK bit
|
||||||
|
VBSACT = 7 ; Vector Block Status, ACTive bit
|
||||||
|
;
|
||||||
|
; BITS in (X or Y) VB CHECK FLAG bit mask:
|
||||||
|
VBCLMT = 0 ; Vector Block Check, LiMiT bit
|
||||||
|
VBCREV = 1 ; Vector Block Check, REVerse delta on limit attain
|
||||||
|
VBCLAT = 3 ; Vector Block Check, coordinate Limit ATtained
|
||||||
|
;
|
||||||
|
; FONT TABLE DISPLACEMENTS for CHARACTER DESCRIPTOR BLOCK:
|
||||||
|
FTBASE = 0x00 ; +0 ; FonT BASE character (normally 0xA0)
|
||||||
|
FTFSX = 0x01 ; +1 ; FonT Frame X Size width
|
||||||
|
FTFSY = 0x02 ; +2 ; FonT Frame Y Size height
|
||||||
|
FTBYTE = 0x03 ; +3 ; FonT X size for char in BYTEs
|
||||||
|
FTYSIZ = 0x04 ; +4 ; FonT Y SIZe height in rows
|
||||||
|
FTPTL = 0x05 ; +5 ; FonT Pattern Table address Low
|
||||||
|
FTPTH = 0x06 ; +6 ; FonT Pattern Table address Hi
|
||||||
|
;
|
||||||
|
; BITS for MAGIC REGISTER (write option) byte:
|
||||||
|
MRSHFT = 0x03 ; Magic Register, mask of SHiFT amount 0-3
|
||||||
|
MRROT = 2 ; Magic Register, write with ROTata bit
|
||||||
|
MRXPND = 3 ; Magic Register, write with eXPaND bit
|
||||||
|
MROR = 4 ; Magic Register, write with OR bit
|
||||||
|
MRXOR = 5 ; Magic Register, write with eXclusive-OR bit
|
||||||
|
MRFLOP = 6 ; Magic Register, write with FLOP bit
|
||||||
|
;
|
||||||
|
; BITS of CONTROL HANDLE Input port:
|
||||||
|
CHUP = 0 ; Control Handle, UP bit
|
||||||
|
CHDOWN = 1 ; Control Handle, DOWN bit
|
||||||
|
CHLEFT = 2 ; Control Handle, joystick LEFT bit
|
||||||
|
CHRIGH = 3 ; Control Handle, joystick RIGHT bit
|
||||||
|
CHTRIG = 4 ; Control Handle, TRIGger bit
|
||||||
|
;
|
||||||
|
; CONTEXT BLOCK Register DISPLACEMENTS:
|
||||||
|
CBIYL = 0x00 ; +0 ; Context Block, IY register Low
|
||||||
|
CBIYH = 0x01 ; +1 ; Context Block, IY register Hi
|
||||||
|
CBIXL = 0x02 ; +2 ; Context Block, IX register Low
|
||||||
|
CBIXH = 0x03 ; +3 ; Context Block, IX register Hi
|
||||||
|
CBE = 0x04 ; +4 ; Context Block, E register
|
||||||
|
CBD = 0x05 ; +5 ; Context Block, D register
|
||||||
|
CBC = 0x06 ; +6 ; Context Block, C register
|
||||||
|
CBB = 0x07 ; +7 ; Context Block, B register
|
||||||
|
CBFLAG = 0x08 ; +8 ; Context Block, FLAGs register
|
||||||
|
CBA = 0x09 ; +9 ; Context Block, A register
|
||||||
|
CBL = 0x0A ; +10 ; Context Block, L register
|
||||||
|
CBH = 0x0B ; +11 ; Context Block, H register
|
||||||
|
;
|
||||||
|
; SENTRY RETURN Codes =ates:
|
||||||
|
SNUL = 0x00 ; Sentry return NULl, nothing happened
|
||||||
|
SCT0 = 0x01 ; Sentry, Counter-Timer 0 has counted down
|
||||||
|
SCT1 = 0x02 ; Sentry, Counter-Timer 1 has counted down
|
||||||
|
SCT2 = 0x03 ; Sentry, Counter-Timer 2 has counted down
|
||||||
|
SCT3 = 0x04 ; Sentry, Counter-Timer 3 has counted down
|
||||||
|
SCT4 = 0x05 ; Sentry, Counter-Timer 4 has counted down
|
||||||
|
SCT5 = 0x06 ; Sentry, Counter-Timer 5 has counted down
|
||||||
|
SCT6 = 0x07 ; Sentry, Counter-Timer 6 has counted down
|
||||||
|
SCT7 = 0x08 ; Sentry, Counter-Timer 7 has counted down
|
||||||
|
SF0 = 0x09 ; Sentry, Flag bit 0 has changed
|
||||||
|
SF1 = 0x0A ; Sentry, Flag bit 1 has changed
|
||||||
|
SF2 = 0x0B ; Sentry, Flag bit 2 has changed
|
||||||
|
SF3 = 0x0C ; Sentry, Flag bit 3 has changed
|
||||||
|
SF4 = 0x0D ; Sentry, Flag bit 4 has changed
|
||||||
|
SF5 = 0x0E ; Sentry, Flag bit 5 has changed
|
||||||
|
SF6 = 0x0F ; Sentry, Flag bit 6 has changed
|
||||||
|
SF7 = 0x10 ; Sentry, Flag bit 7 has changed
|
||||||
|
SSEC = 0x11 ; Sentry, SEConds timer has counted down
|
||||||
|
SKYU = 0x12 ; Sentry, KeY is now Up
|
||||||
|
SKYD = 0x13 ; Sentry, KeY is now Down
|
||||||
|
ST0 = 0x14 ; Sentry, Trigger 0 for player 1 has changed
|
||||||
|
SJ0 = 0x15 ; Sentry, Joystick 0 for player 1 has changed
|
||||||
|
ST1 = 0x16 ; Sentry, Trigger 1 for player 2 has changed
|
||||||
|
SJ1 = 0x17 ; Sentry, Joystick 1 for player 2 has changed
|
||||||
|
ST2 = 0x18 ; Sentry, Trigger 2 for player 3 has changed
|
||||||
|
SJ2 = 0x19 ; Sentry, Joystick 2 for player 3 has changed
|
||||||
|
ST3 = 0x1A ; Sentry, Trigger 3 for player 4 has changed
|
||||||
|
SJ3 = 0x1B ; Sentry, Joystick 3 for player 4 has changed
|
||||||
|
SP0 = 0x1C ; Sentry, POTentiometer 0 has changed
|
||||||
|
SP1 = 0x1D ; Sentry, POTentiometer 1 has changed
|
||||||
|
SP2 = 0x1E ; Sentry, POTentiometer 2 has changed
|
||||||
|
SP3 = 0x1F ; Sentry, POTentiometer 3 has changed
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; ********************************
|
||||||
|
; * Home Video Game PORT =ates *
|
||||||
|
; ********************************
|
||||||
|
;
|
||||||
|
; OUTPUT Ports for VIRTUAL COLOR:
|
||||||
|
COL0R = 0x00 ; &(0)= ; write COLor 0 Right
|
||||||
|
COL1R = 0x01 ; &(1)= ; write COLor 1 Right
|
||||||
|
COL2R = 0x02 ; &(2)= ; write COLor 2 Right
|
||||||
|
COL3R = 0x03 ; &(3)= ; write COLor 3 Right
|
||||||
|
COL0L = 0x04 ; &(4)= ; write COLor 0 Left
|
||||||
|
COL1L = 0x05 ; &(5)= ; write COLor 1 Left
|
||||||
|
COL2L = 0x06 ; &(6)= ; write COLor 2 Left
|
||||||
|
COL3L = 0x07 ; &(7)= ; write COLor 3 Left
|
||||||
|
HORCB = 0x09 ; &(9)= ; write HORizontal Color Boundary
|
||||||
|
VERBL = 0x0A ;&(10)= ; write VERtical Blanking Line
|
||||||
|
COLBX = 0x0B ;&(11)= ; write COLor BloCK multi-port
|
||||||
|
;
|
||||||
|
; OUTPUT Ports for MUSIC and SOUNDS:
|
||||||
|
TONMO = 0x10 ;&(16)= ; write TONe Master Oscillator
|
||||||
|
TONEA = 0x11 ;&(17)= ; write TONe A oscillator
|
||||||
|
TONEB = 0x12 ;&(18)= ; write TONe B oscillator
|
||||||
|
TONEC = 0x13 ;&(19)= ; write TONe C oscillator
|
||||||
|
VIBRA = 0x14 ;&(20)= ; write VIBRAto frequency & range
|
||||||
|
VOLC = 0x15 ;&(21)= ; write VOLume of tone C
|
||||||
|
VOLAB = 0x16 ;&(22)= ; write VOLumes of tones A & B
|
||||||
|
VOLN = 0x17 ;&(23)= ; write VOLume of Noise
|
||||||
|
SNDBX = 0x18 ;&(24)= ; write SouND BloCK multi-port
|
||||||
|
;
|
||||||
|
; INTERRUPT and CONTROL OUTPUT Ports:
|
||||||
|
CONCM = 0x08 ; &(8)= ; write 0 for CONsumer, 1 for CoMmercial mode
|
||||||
|
MAGIC = 0x0C ;&(12)= ; write MAGIC register
|
||||||
|
INFBK = 0x0D ;&(13)= ; write INterrupt FeedBacK
|
||||||
|
INMOD = 0x0E ;&(14)= ; write INterrupt MODe
|
||||||
|
INLIN = 0x0F ;&(15)= ; write INterrupt LINe
|
||||||
|
XPAND = 0x19 ;&(25)= ; eXPANDer pixel definition port
|
||||||
|
;
|
||||||
|
; INTERRUPT and INTERCEPT INPUT Ports:
|
||||||
|
INTST = 0x08 ; =&(8) ; read INTercept STatus
|
||||||
|
VERAF = 0x0E ;=&(14) ; read VERtical Address Feedback
|
||||||
|
HORAF = 0x0F ;=&(15) ; read HORizontal Address Feedback
|
||||||
|
;
|
||||||
|
; HAND CONTROL INPUT Ports:
|
||||||
|
SW0 = 0x10 ;=&(16) ; read SWitch bank 0 for player 1 hand control
|
||||||
|
SW1 = 0x11 ;=&(17) ; read SWitch bank 1 for player 2 hand control
|
||||||
|
SW2 = 0x12 ;=&(18) ; read SWitch bank 2 for player 3 hand control
|
||||||
|
SW3 = 0x13 ;=&(19) ; read SWitch bank 3 for player 4 hand control
|
||||||
|
POT0 = 0x1C ;=&(28) ; read POTentiometer 0 for player 1 knob
|
||||||
|
POT1 = 0x1D ;=&(29) ; read POTentiometer 1 for player 2 knob
|
||||||
|
POT2 = 0x1E ;=&(30) ; read POTentiometer 2 for player 3 knob
|
||||||
|
POT3 = 0x1F ;=&(31) ; read POTentiometer 3 for player 4 knob
|
||||||
|
;
|
||||||
|
; KEYBOARD INPUT Ports:
|
||||||
|
KEY0 = 0x14 ;=&(20) ; KEYboard column 0 (right side)
|
||||||
|
KEY1 = 0x15 ;=&(21) ; KEYboard column 1 (center right)
|
||||||
|
KEY2 = 0x16 ;=&(22) ; KEYboard column 2 (center left)
|
||||||
|
KEY3 = 0x17 ;=&(23) ; KEYboard column 3 (left side)
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; ***************************************
|
||||||
|
; * Home Video Game SYSTEM CALL Indexes *
|
||||||
|
; ***************************************
|
||||||
|
;
|
||||||
|
; USER PROGRAM Interface:
|
||||||
|
INTPC = 0x00 ; # 0 ; INTerPret with Context create
|
||||||
|
XINTC = 0x02 ; # 2 ; eXit INTerpreter with Context
|
||||||
|
RCALL = 0x04 ; # 4 ; Real CALL asm language subroutine
|
||||||
|
MCALL = 0x06 ; # 6 ; Macro CALL interpreter subroutine
|
||||||
|
MRET = 0x08 ; # 8 ; Macro RETurn from interpreter subroutine
|
||||||
|
MJUMP = 0x0A ; # 10 ; Macro JUMP to interpreter subroutine
|
||||||
|
SUCK = 0x0C ; # 12 ; SUCK inline args into context block
|
||||||
|
;
|
||||||
|
; SCHEDULER Routines:
|
||||||
|
ACTINT = 0x0E ; # 14 ; ACTivate sub timer INTerrupts
|
||||||
|
DECCTS = 0x10 ; # 16 ; DECrement CTS under mask
|
||||||
|
;
|
||||||
|
; MUSIC and SOUNDS:
|
||||||
|
BMUSIC = 0x12 ; # 18 ; Begin playing MUSIC
|
||||||
|
EMUSIC = 0x14 ; # 20 ; End playing MUSIC
|
||||||
|
;
|
||||||
|
; SCREEN HANDLER Routines:
|
||||||
|
SETOUT = 0x16 ; # 22 ; SET some OUTput ports
|
||||||
|
COLSET = 0x18 ; # 24 ; COLors SET
|
||||||
|
FILL = 0x1A ; # 26 ; FILL memory with data
|
||||||
|
RECTAN = 0x1C ; # 28 ; paint a RECTANgle
|
||||||
|
VWRITR = 0x1E ; # 30 ; Vector WRITe Relative
|
||||||
|
WRITR = 0x20 ; # 32 ; WRITe Relative
|
||||||
|
WRITP = 0x22 ; # 34 ; WRITe with Pattern size lookup
|
||||||
|
WRIT = 0x24 ; # 36 ; WRITe with sizes provided
|
||||||
|
WRITA = 0x26 ; # 38 ; WRITe Absolute
|
||||||
|
VBLANK = 0x28 ; # 40 ; Vector BLANK area
|
||||||
|
BLANK = 0x2A ; # 42 ; BLANK area
|
||||||
|
SAVE = 0x2C ; # 44 ; SAVE area
|
||||||
|
RESTOR = 0x2E ; # 46 ; RESTORe area
|
||||||
|
SCROLL = 0x30 ; # 48 ; SCROLL area of screen
|
||||||
|
;
|
||||||
|
CHRDIS = 0x32 ; # 50 ; CHaRacter DISplay
|
||||||
|
STRDIS = 0x34 ; # 52 ; STRing DISplay
|
||||||
|
DISNUM = 0x36 ; # 54 ; DISplay NUMber
|
||||||
|
;
|
||||||
|
RELABS = 0x38 ; # 56 ; RELative to ABSolute conversion
|
||||||
|
RELAB1 = 0x3A ; # 58 ; RELative to non-magic ABSolute
|
||||||
|
VECTC = 0x3C ; # 60 ; VECTor move single Coordinate
|
||||||
|
VECT = 0x3E ; # 62 ; VECTor move coordinate pair
|
||||||
|
;
|
||||||
|
; HUMAN INTERFACE Routines:
|
||||||
|
KCTASC = 0x40 ; # 64 ; Key Code in B To ASCii
|
||||||
|
SENTRY = 0x42 ; # 66 ; SENse TRansition Y
|
||||||
|
DOIT = 0x44 ; # 68 ; DOIT table, branch to translation handler
|
||||||
|
DOITB = 0x46 ; # 70 ; DOIT table, use B instead of A
|
||||||
|
PIZBRK = 0x48 ; # 72 ; take a PIZza BReaK
|
||||||
|
MENU = 0x4A ; # 74 ; display a MENU
|
||||||
|
GETPAR = 0x4C ; # 76 ; GET game PARameter from user
|
||||||
|
GETNUM = 0x4E ; # 78 ; GET NUMber from user
|
||||||
|
PAWS = 0x50 ; # 80 ; PAUSE
|
||||||
|
DISTIM = 0x52 ; # 82 ; DISplay TIMe
|
||||||
|
INCSCR = 0x54 ; # 84 ; INCrement SCoRe
|
||||||
|
;
|
||||||
|
; MATH Routines:
|
||||||
|
INDEXN = 0x56 ; # 86 ; INDEX Nibble by C
|
||||||
|
STOREN = 0x58 ; # 88 ; STORE Nibble in A by C
|
||||||
|
INDEXW = 0x5A ; # 90 ; INDEX Word by A
|
||||||
|
INDEXB = 0x5C ; # 92 ; INDEX Byte by A
|
||||||
|
MOVE = 0x5E ; # 94 ; MOVE block transfer
|
||||||
|
SHIFTU = 0x60 ; # 96 ; SHIFT Up digit in A
|
||||||
|
BCDADD = 0x62 ; # 98 ; BCD ADDition
|
||||||
|
BCDSUB = 0x64 ;# 100 ; BCD SUBtraction
|
||||||
|
BCDMUL = 0x66 ;# 102 ; BCD MULtiplication
|
||||||
|
BCDDIV = 0x68 ;# 104 ; BCD DIVision
|
||||||
|
BCDCHS = 0x6A ;# 106 ; BCD CHange Sign
|
||||||
|
BCDNEG = 0x6C ;# 108 ; BCD NEGate to decimal
|
||||||
|
DADD = 0x6E ;# 110 ; Decimal ADDition
|
||||||
|
DSMG = 0x70 ;# 112 ; Decimal convert to Sign MaGnitude
|
||||||
|
DABS = 0x72 ;# 114 ; Decimal ABSolute value
|
||||||
|
NEGT = 0x74 ;# 116 ; decimal NEGaTe
|
||||||
|
RANGED = 0x76 ;# 118 ; RANGED random number
|
||||||
|
QUIT = 0x78 ;# 120 ; QUIT cassette execution
|
||||||
|
SETB = 0x7A ;# 122 ; SET Byte
|
||||||
|
SETW = 0x7C ;# 124 ; SET Word
|
||||||
|
MSKTD = 0x7E ;# 127 ; MaSK joystick in B To Deltas
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; ***************************
|
||||||
|
; * SYSTEM RAM MEMORY Cells *
|
||||||
|
; ***************************
|
||||||
|
WASTE = 0x0FFF
|
||||||
|
WASTER = WASTE
|
||||||
|
;
|
||||||
|
SYSRAM = 0x4FCE ; Resides at the highest possible address
|
||||||
|
BEGRAM = SYSRAM ; typically used for initial Stack Pointer
|
||||||
|
; Used by MUSIC PROCESSOR:
|
||||||
|
MUZPC = 0x4FCE ; MUSic Program Counter
|
||||||
|
MUZSP = 0x4FD0 ; MUSic Stack Pointer
|
||||||
|
PVOLAB = 0x4FD2 ; Preset VOLume for tones A and B
|
||||||
|
PVOLMC = 0x4FD3 ; Preset VOLuMe for tone C and Noise Mode
|
||||||
|
VOICES = 0x4FD4 ; music VOICES mask
|
||||||
|
; COUNTER TIMERS (used by DECCTS,ACTINT,CTIMER):
|
||||||
|
CT0 = 0x4FD5 ; Counter Timer 0
|
||||||
|
CT1 = 0x4FD6 ; Counter Timer 1
|
||||||
|
CT2 = 0x4FD7 ; Counter Timer 2
|
||||||
|
CT3 = 0x4FD8 ; Counter Timer 3
|
||||||
|
CT4 = 0x4FD9 ; Counter Timer 4
|
||||||
|
CT5 = 0x4FDA ; Counter Timer 5
|
||||||
|
CT6 = 0x4FDB ; Counter Timer 6
|
||||||
|
CT7 = 0x4FDC ; Counter Timer 7
|
||||||
|
;Used by SENTRY to track controls:
|
||||||
|
CNT = 0x4FDD ; Counter update & Number Tracking
|
||||||
|
SEMI4S = 0x4FDE ; SEMAPHORE flag bitS
|
||||||
|
OPOT0 = 0x4FDF ; Old POT 0 tracking byte
|
||||||
|
OPOT1 = 0x4FE0 ; Old POT 1 tracking byte
|
||||||
|
OPOT2 = 0x4FE1 ; Old POT 2 tracking byte
|
||||||
|
OPOT3 = 0x4FE2 ; Old POT 3 tracking byte
|
||||||
|
KEYSEX = 0x4FE3 ; KEYS-EX tracking byte
|
||||||
|
OSW0 = 0x4FE4 ; Old SWitch 0 tracking byte
|
||||||
|
OSW1 = 0x4FE5 ; Old SWitch 1 tracking byte
|
||||||
|
OSW2 = 0x4FE6 ; Old SWitch 2 tracking byte
|
||||||
|
OSW3 = 0x4FE7 ; Old SWitch 3 tracking byte
|
||||||
|
COLLST = 0x4FE8 ; COLset LaST address for P.B. A
|
||||||
|
; Used by STIMER:
|
||||||
|
DURAT = 0x4FEA ; note DURATion
|
||||||
|
TMR60 = 0x4FEB ; TiMeR for SIXTYths of sec
|
||||||
|
TIMOUT = 0x4FEC ; TIMer for blackOUT
|
||||||
|
GTSECS = 0x4FED ; Game Time SECondS
|
||||||
|
GTMINS = 0x4FEE ; Game Time MINuteS
|
||||||
|
; Used by MENU:
|
||||||
|
RANSHT = 0x4FEF ; RANdom number SHifT register
|
||||||
|
NUMPLY = 0x4FF3 ; NUMber of PLaYers
|
||||||
|
ENDSCR = 0x4FF4 ; END SCoRe to 'play to'
|
||||||
|
MRLOCK = 0x4FF7 ; Magic Register LOCK out flag
|
||||||
|
GAMSTB = 0x4FF8 ; GAMe STatus Byte
|
||||||
|
PRIOR = 0x4FF9 ; PRIOR music protect flag
|
||||||
|
SENFLG = 0x4FFA ; SENtry control seizure FLaG
|
||||||
|
; User UPI Routines, even numbers from 0x80 to 0xFE ( + 1 for SUCK):
|
||||||
|
UMARGT = 0x4FFB ; User Mask ARGument Table + (routine / 2)
|
||||||
|
USERTB = 0x4FFD ; USER Table Base + routine = JumP address
|
||||||
|
;
|
||||||
|
URINAL = 0x4FFF ; WASTER flushes here!
|
||||||
|
;
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; MACROs to generate SYSTEM CALLs:
|
||||||
|
.macro SYSTEM NUMBA
|
||||||
|
rst 0x38
|
||||||
|
.db NUMBA
|
||||||
|
; .if NUMBA = INTPC
|
||||||
|
;INTPCC = 1
|
||||||
|
; .endif
|
||||||
|
.endm
|
||||||
|
; MACRO to generate SYSTEM CALL with SUCK option ON:
|
||||||
|
.macro SYSSUK UMBA
|
||||||
|
rst 0x38
|
||||||
|
.db UMBA + 1
|
||||||
|
; .if UMBA = INTPC
|
||||||
|
;INTPCC = 1
|
||||||
|
; .endif
|
||||||
|
.endm
|
||||||
|
; MACROs to generate MACRO INTERPRETER CALLs:
|
||||||
|
; INTERPRET without INLINE SUCK:
|
||||||
|
.macro DONT CID
|
||||||
|
.db CID
|
||||||
|
.endm
|
||||||
|
; INTERPRET with INLINE SUCK option ON:
|
||||||
|
.macro DO CID
|
||||||
|
.db CID + 1
|
||||||
|
.endm
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
#define TEST
|
#define TEST
|
||||||
|
|
||||||
@ -46,13 +46,28 @@ __sfr __at(0x13) hw_p4ctrl; // player controls
|
|||||||
#define M_SHIFT(x) ((x)&3)
|
#define M_SHIFT(x) ((x)&3)
|
||||||
#define XPAND_COLORS(off,on) (((off)&3) | (((on)&3)<<2))
|
#define XPAND_COLORS(off,on) (((off)&3) | (((on)&3)<<2))
|
||||||
|
|
||||||
|
// font options
|
||||||
|
#define OPT_1x1 0x00
|
||||||
|
#define OPT_2x2 0x40
|
||||||
|
#define OPT_4x4 0x80
|
||||||
|
#define OPT_8x8 0xc0
|
||||||
|
#define OPT_XOR 0x20
|
||||||
|
#define OPT_OR 0x10
|
||||||
|
#define OPT_ON(n) ((n)<<2)
|
||||||
|
#define OPT_OFF(n) ((n))
|
||||||
|
|
||||||
|
// bcd options
|
||||||
|
#define DISBCD_SML 0x40
|
||||||
|
#define DISBCD_NOZERO 0x80
|
||||||
|
|
||||||
/// GRAPHICS FUNCTIONS
|
/// GRAPHICS FUNCTIONS
|
||||||
|
|
||||||
#define VHEIGHT 89 // number of scanlines
|
#define VHEIGHT 89 // number of scanlines
|
||||||
#define VBWIDTH 40 // number of bytes per scanline
|
#define VBWIDTH 40 // number of bytes per scanline
|
||||||
#define PIXWIDTH 160 // 4 pixels per byte
|
#define PIXWIDTH 160 // 4 pixels per byte
|
||||||
|
|
||||||
#define EXIT_CLIPDEST(addr) if ((((word)addr)&0xfff) >= 0xe10) return
|
//#define EXIT_CLIPDEST(addr) if ((((word)addr)&0xfff) >= 0xe10) return
|
||||||
|
#define EXIT_CLIPDEST(addr)
|
||||||
|
|
||||||
byte __at (0x0000) vmagic[VHEIGHT][VBWIDTH];
|
byte __at (0x0000) vmagic[VHEIGHT][VBWIDTH];
|
||||||
byte __at (0x4000) vidmem[VHEIGHT][VBWIDTH];
|
byte __at (0x4000) vidmem[VHEIGHT][VBWIDTH];
|
||||||
@ -90,23 +105,25 @@ byte SENFLG; // sentry control
|
|||||||
byte* UMARGT; // user mask table (-64 bytes)
|
byte* UMARGT; // user mask table (-64 bytes)
|
||||||
word* USERTB; // user routine table (-128 bytes)
|
word* USERTB; // user routine table (-128 bytes)
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
#define MAIN _main
|
||||||
|
#else
|
||||||
|
#define MAIN 0x2000
|
||||||
|
#endif
|
||||||
|
|
||||||
// start routine @ 0x0
|
// start routine @ 0x0
|
||||||
void bios_start() __naked {
|
void bios_start() __naked {
|
||||||
__asm
|
__asm
|
||||||
DI ; disable interrupts
|
DI ; disable interrupts
|
||||||
LD HL,#0x2000
|
LD HL,#MAIN
|
||||||
LD A,(HL) ; A <- mem[0x2000]
|
LD A,(HL) ; A <- mem[0x2000]
|
||||||
CP #0x55 ; found sentinel byte? ($55)
|
CP #0x55 ; found sentinel byte? ($55)
|
||||||
JP Z,FoundSentinel ; yes, load program
|
JP Z,FoundSentinel ; yes, load program
|
||||||
#ifndef TEST
|
JP MAIN
|
||||||
JP 0x2000 ; jump to $2000
|
|
||||||
#else
|
|
||||||
JP _main ; jump to test program
|
|
||||||
#endif
|
|
||||||
FoundSentinel:
|
FoundSentinel:
|
||||||
LD SP,#0x4fce ; position stack below BIOS vars
|
LD SP,#0x4fce ; position stack below BIOS vars
|
||||||
CALL _bios_init ; misc. bios init routines
|
CALL _bios_init ; misc. bios init routines
|
||||||
LD HL,#0x2005 ; cartridge start vector
|
LD HL,#(MAIN+5) ; cartridge start vector
|
||||||
LD A,(HL)
|
LD A,(HL)
|
||||||
INC HL
|
INC HL
|
||||||
LD H,(HL)
|
LD H,(HL)
|
||||||
@ -196,10 +213,6 @@ void STIMER() {
|
|||||||
void CTIMER() {
|
void CTIMER() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bios_init() {
|
|
||||||
memset((void*)0x4fce, 0, 0x5000-0x4fce);
|
|
||||||
}
|
|
||||||
|
|
||||||
///// INTERPRETER
|
///// INTERPRETER
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -225,6 +238,24 @@ typedef struct {
|
|||||||
#define REG_DE (REG_D|REG_E)
|
#define REG_DE (REG_D|REG_E)
|
||||||
#define REG_BC (REG_B|REG_C)
|
#define REG_BC (REG_B|REG_C)
|
||||||
|
|
||||||
|
#define _IY (ctx->regs.w.iy)
|
||||||
|
#define _IX (ctx->regs.w.ix)
|
||||||
|
#define _DE (ctx->regs.w.de)
|
||||||
|
#define _BC (ctx->regs.w.bc)
|
||||||
|
#define _AF (ctx->regs.w.af)
|
||||||
|
#define _HL (ctx->regs.w.hl)
|
||||||
|
#define _IXL (ctx->regs.b.ixl)
|
||||||
|
#define _IXH (ctx->regs.b.ixh)
|
||||||
|
#define _IYL (ctx->regs.b.iyl)
|
||||||
|
#define _IYH (ctx->regs.b.iyh)
|
||||||
|
#define _E (ctx->regs.b.e)
|
||||||
|
#define _D (ctx->regs.b.d)
|
||||||
|
#define _C (ctx->regs.b.c)
|
||||||
|
#define _B (ctx->regs.b.b)
|
||||||
|
#define _A (ctx->regs.b.a)
|
||||||
|
#define _L (ctx->regs.b.l)
|
||||||
|
#define _H (ctx->regs.b.h)
|
||||||
|
|
||||||
typedef void (Routine)();
|
typedef void (Routine)();
|
||||||
typedef void (SysRoutine)(ContextBlock *ctx);
|
typedef void (SysRoutine)(ContextBlock *ctx);
|
||||||
|
|
||||||
@ -248,7 +279,7 @@ void EXIT(ContextBlock *ctx) {
|
|||||||
|
|
||||||
// jumps to HL
|
// jumps to HL
|
||||||
void RCALL(ContextBlock *ctx) {
|
void RCALL(ContextBlock *ctx) {
|
||||||
((Routine*)ctx->regs.w.hl)();
|
((Routine*)_HL)();
|
||||||
}
|
}
|
||||||
|
|
||||||
// start interpreting at HL
|
// start interpreting at HL
|
||||||
@ -263,35 +294,35 @@ void MRET(ContextBlock *ctx) {
|
|||||||
|
|
||||||
// jump within MCALL
|
// jump within MCALL
|
||||||
void MJUMP(ContextBlock *ctx) {
|
void MJUMP(ContextBlock *ctx) {
|
||||||
ctx->params = (byte*) ctx->regs.w.hl; // TODO?
|
ctx->params = (byte*) _HL; // TODO?
|
||||||
}
|
}
|
||||||
|
|
||||||
void suckParams(ContextBlock *ctx, byte argmask) {
|
void suckParams(ContextBlock *ctx, byte argmask) {
|
||||||
byte* dest = (byte*) ctx;
|
byte* dest = (byte*) ctx;
|
||||||
byte* src = ctx->params;
|
byte* src = ctx->params;
|
||||||
if (argmask & REG_IX) {
|
if (argmask & REG_IX) {
|
||||||
ctx->regs.b.ixl = *src++;
|
_IXL = *src++;
|
||||||
ctx->regs.b.ixh = *src++;
|
_IXH = *src++;
|
||||||
}
|
}
|
||||||
if (argmask & REG_E)
|
if (argmask & REG_E)
|
||||||
ctx->regs.b.e = *src++;
|
_E = *src++;
|
||||||
if (argmask & REG_D)
|
if (argmask & REG_D)
|
||||||
ctx->regs.b.d = *src++;
|
_D = *src++;
|
||||||
if (argmask & REG_C)
|
if (argmask & REG_C)
|
||||||
ctx->regs.b.c = *src++;
|
_C = *src++;
|
||||||
if (argmask & REG_B)
|
if (argmask & REG_B)
|
||||||
ctx->regs.b.b = *src++;
|
_B = *src++;
|
||||||
if (argmask & REG_A)
|
if (argmask & REG_A)
|
||||||
ctx->regs.b.a = *src++;
|
_A = *src++;
|
||||||
if (argmask & REG_HL) {
|
if (argmask & REG_HL) {
|
||||||
ctx->regs.b.l = *src++;
|
_L = *src++;
|
||||||
ctx->regs.b.h = *src++;
|
_H = *src++;
|
||||||
}
|
}
|
||||||
ctx->params = src;
|
ctx->params = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SUCK(ContextBlock* ctx) {
|
void SUCK(ContextBlock* ctx) {
|
||||||
suckParams(ctx, ctx->regs.b.b);
|
suckParams(ctx, _B);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACTINT(ContextBlock *ctx) {
|
void ACTINT(ContextBlock *ctx) {
|
||||||
@ -309,53 +340,114 @@ __endasm;
|
|||||||
|
|
||||||
// Outputs D to port 0A, B to port 09, A to port 0E.
|
// Outputs D to port 0A, B to port 09, A to port 0E.
|
||||||
void SETOUT(ContextBlock *ctx) {
|
void SETOUT(ContextBlock *ctx) {
|
||||||
hw_verbl = ctx->regs.b.d;
|
hw_verbl = _D;
|
||||||
hw_horcb = ctx->regs.b.b;
|
hw_horcb = _B;
|
||||||
hw_inmod = ctx->regs.b.a;
|
hw_inmod = _A;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets color palettes from (HL)
|
// sets color palettes from (HL)
|
||||||
void COLSET(ContextBlock *ctx) {
|
void COLSET(ContextBlock *ctx) {
|
||||||
byte* palette = (byte*) ctx->regs.w.hl;
|
byte* palette = (byte*) _HL;
|
||||||
hw_col0r = *palette++;
|
|
||||||
hw_col1r = *palette++;
|
|
||||||
hw_col2r = *palette++;
|
|
||||||
hw_col3r = *palette++;
|
|
||||||
hw_col0l = *palette++;
|
|
||||||
hw_col1l = *palette++;
|
|
||||||
hw_col2l = *palette++;
|
|
||||||
hw_col3l = *palette++;
|
hw_col3l = *palette++;
|
||||||
|
hw_col2l = *palette++;
|
||||||
|
hw_col1l = *palette++;
|
||||||
|
hw_col0l = *palette++;
|
||||||
|
hw_col3r = *palette++;
|
||||||
|
hw_col2r = *palette++;
|
||||||
|
hw_col1r = *palette++;
|
||||||
|
hw_col0r = *palette++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stores A in BC bytes starting at location DE.
|
// Stores A in BC bytes starting at location DE.
|
||||||
void FILL(ContextBlock *ctx) {
|
void FILL(ContextBlock *ctx) {
|
||||||
byte* dest = (byte*) ctx->regs.w.de;
|
byte* dest = (byte*) _DE;
|
||||||
word count = ctx->regs.w.bc;
|
word count = _BC;
|
||||||
byte val = ctx->regs.b.a;
|
byte val = _A;
|
||||||
memset(dest, val, count);
|
memset(dest, val, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hline(byte x1, byte x2, byte y, byte pattern) {
|
||||||
|
byte xb1 = x1/4;
|
||||||
|
byte xb2 = x2/4;
|
||||||
|
byte* dest = &vmagic[y][xb1];
|
||||||
|
signed char nbytes = xb2 - xb1;
|
||||||
|
hw_magic = M_SHIFT(x1) | M_XOR;
|
||||||
|
while (--nbytes > 0) {
|
||||||
|
*dest++ = pattern;
|
||||||
|
}
|
||||||
|
if (x2&3) *dest = 0;
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill rect (E,D,C,B) color A
|
||||||
|
void RECTAN(const ContextBlock *ctx) {
|
||||||
|
for (byte y=_D; y<_D+_B; y++) {
|
||||||
|
hline(_E, _E+_C, y, _A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char BIGFONT[HICHAR-LOCHAR+1][7] = {/*{count:68,w:8,h:7,brev:1}*/
|
const char BIGFONT[HICHAR-LOCHAR+1][7] = {/*{count:68,w:8,h:7,brev:1}*/
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00 },{ 0x00,0x20,0x20,0x20,0x00,0x20,0x00 },{ 0x50,0x50,0x50,0x00,0x00,0x00,0x00 },{ 0x00,0x50,0xF8,0x50,0xF8,0x50,0x00 },{ 0x00,0xF8,0xA0,0xF8,0x28,0xF8,0x00 },{ 0x00,0xC8,0xD0,0x20,0x58,0x98,0x00 },{ 0x00,0xE0,0xA8,0xF8,0x90,0xF8,0x00 },{ 0x40,0x40,0x40,0x00,0x00,0x00,0x00 },{ 0x30,0x20,0x20,0x20,0x20,0x20,0x30 },{ 0x60,0x20,0x20,0x20,0x20,0x20,0x60 },{ 0x00,0x20,0xA8,0x70,0xA8,0x20,0x00 },{ 0x00,0x20,0x20,0xF8,0x20,0x20,0x00 },{ 0x00,0x00,0x00,0x00,0x60,0x60,0x40 },{ 0x00,0x00,0x00,0xF8,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0x60,0x60,0x00 },{ 0x00,0x08,0x10,0x20,0x40,0x80,0x00 },{ 0x00,0xF8,0x88,0xE8,0x88,0xF8,0x00 },{ 0x00,0x10,0x30,0x50,0x10,0x10,0x00 },{ 0x00,0xF8,0x08,0xF8,0x80,0xF8,0x00 },{ 0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00 },{ 0x00,0x38,0x48,0x88,0xF8,0x08,0x00 },{ 0x00,0xF8,0x80,0xF8,0x08,0xF8,0x00 },{ 0x00,0xF8,0x80,0xF8,0x88,0xF8,0x00 },{ 0x00,0xF8,0x08,0x10,0x20,0x40,0x00 },{ 0x00,0xF8,0x88,0xF8,0x88,0xF8,0x00 },{ 0x00,0xF8,0x88,0xF8,0x08,0xF8,0x00 },{ 0x00,0x30,0x30,0x00,0x30,0x30,0x00 },{ 0x00,0x30,0x30,0x00,0x30,0x30,0x20 },{ 0x08,0x10,0x20,0x40,0x20,0x10,0x08 },{ 0x00,0x00,0xF8,0x00,0xF8,0x00,0x00 },{ 0x40,0x20,0x10,0x08,0x10,0x20,0x40 },{ 0x00,0xF8,0x08,0x78,0x00,0x60,0x00 },{ 0x00,0xF8,0xA8,0xB8,0x80,0xF8,0x00 },{ 0x00,0xF8,0x88,0xF8,0x88,0x88,0x00 },{ 0x00,0xF0,0x90,0xF8,0x88,0xF8,0x00 },{ 0x00,0xF8,0x80,0x80,0x80,0xF8,0x00 },{ 0x00,0xE0,0x90,0x88,0x88,0xF8,0x00 },{ 0x00,0xF8,0x80,0xF8,0x80,0xF8,0x00 },{ 0x00,0xF8,0x80,0xF8,0x80,0x80,0x00 },{ 0x00,0xF8,0x80,0xB8,0x88,0xF8,0x00 },{ 0x00,0x88,0x88,0xF8,0x88,0x88,0x00 },{ 0x00,0x40,0x40,0x40,0x40,0x40,0x00 },{ 0x00,0x08,0x08,0x88,0x88,0xF8,0x00 },{ 0x00,0x88,0x90,0xA0,0x90,0x88,0x00 },{ 0x00,0x80,0x80,0x80,0x80,0xF8,0x00 },{ 0x00,0xFE,0x92,0x92,0x92,0x92,0x00 },{ 0x00,0x88,0xC8,0xA8,0x98,0x88,0x00 },{ 0x00,0xF8,0x88,0x88,0x88,0xF8,0x00 },{ 0x00,0xF8,0x88,0x88,0xF8,0x80,0x00 },{ 0x00,0xF8,0x88,0xA8,0xA8,0xF8,0x10 },{ 0x00,0xF8,0x88,0xF8,0x90,0x88,0x00 },{ 0x00,0xF8,0x80,0xF8,0x08,0xF8,0x00 },{ 0x00,0xF8,0x20,0x20,0x20,0x20,0x00 },{ 0x00,0x88,0x88,0x88,0x88,0xF8,0x00 },{ 0x00,0x88,0x88,0x90,0xA0,0xC0,0x00 },{ 0x00,0x92,0x92,0x92,0x92,0xFE,0x00 },{ 0x00,0x88,0x50,0x20,0x50,0x88,0x00 },{ 0x00,0x88,0x88,0xF8,0x08,0xF8,0x00 },{ 0x00,0xF8,0x10,0x20,0x40,0xF8,0x00 },{ 0x38,0x20,0x20,0x20,0x20,0x20,0x38 },{ 0x00,0x80,0x40,0x20,0x10,0x08,0x00 },{ 0x70,0x10,0x10,0x10,0x10,0x10,0x70 },{ 0x00,0x20,0x70,0xA8,0x20,0x20,0x00 },{ 0x00,0x20,0x40,0xF8,0x40,0x20,0x00 },{ 0x00,0x20,0x20,0xA8,0x70,0x20,0x00 },{ 0x00,0x20,0x10,0xF8,0x10,0x20,0x00 },{ 0x00,0x88,0x50,0x20,0x50,0x88,0x00 },{ 0x00,0x20,0x00,0xF8,0x00,0x20,0x00 }};
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00},{0x20,0x20,0x20,0x20,0x00,0x00,0x20},{0x50,0x50,0x00,0x00,0x00,0x00,0x00},{0x48,0xFC,0x48,0x48,0x48,0xFC,0x48},{0x20,0x78,0x80,0x70,0x08,0xF0,0x20},{0x00,0x48,0x10,0x20,0x40,0x90,0x00},{0x60,0x90,0x60,0xA0,0xA8,0x90,0x68},{0x60,0x60,0x20,0x00,0x00,0x00,0x00},{0x20,0x40,0x40,0x40,0x40,0x40,0x20},{0x40,0x20,0x20,0x20,0x20,0x20,0x40},{0x00,0xA8,0x70,0xF8,0x70,0xA8,0x00},{0x00,0x20,0x20,0xF8,0x20,0x20,0x00},{0x00,0x00,0x00,0x00,0x60,0x20,0x40},{0x00,0x00,0x00,0xF0,0x00,0x00,0x00},{0x00,0x00,0x00,0x00,0x00,0x60,0x60},{0x00,0x08,0x10,0x20,0x40,0x80,0x00},{0x70,0x88,0x88,0xA8,0x88,0x88,0x70},{0x20,0x60,0x20,0x20,0x20,0x20,0x70},{0x70,0x88,0x08,0x30,0x40,0x80,0xF8},{0x70,0x88,0x08,0x70,0x08,0x88,0x70},{0x10,0x30,0x50,0x90,0xF8,0x10,0x10},{0xF8,0x80,0x80,0x70,0x08,0x88,0x70},{0x70,0x88,0x80,0xF0,0x88,0x88,0x70},{0xF8,0x88,0x10,0x20,0x20,0x20,0x20},{0x70,0x88,0x88,0x70,0x88,0x88,0x70},{0x70,0x88,0x88,0x78,0x08,0x88,0x70},{0x00,0x00,0x60,0x00,0x60,0x00,0x00},{0x00,0x00,0x60,0x00,0x60,0x20,0x40},{0x10,0x20,0x40,0x80,0x40,0x20,0x10},{0x00,0x00,0xF8,0x00,0xF8,0x00,0x00},{0x40,0x20,0x10,0x08,0x10,0x20,0x40},{0x70,0x08,0x08,0x30,0x20,0x00,0x20},{0x70,0x88,0xB8,0xA8,0x90,0x80,0x70},{0x70,0x88,0x88,0xF8,0x88,0x88,0x88},{0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0},{0x70,0x88,0x80,0x80,0x80,0x88,0x70},{0xF0,0x88,0x88,0x88,0x88,0x88,0xF0},{0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8},{0xF8,0x80,0x80,0xF0,0x80,0x80,0x80},{0x70,0x88,0x80,0xB0,0x88,0x88,0x70},{0x88,0x88,0x88,0xF8,0x88,0x88,0x88},{0x70,0x20,0x20,0x20,0x20,0x20,0x70},{0x08,0x08,0x08,0x08,0x88,0x88,0x70},{0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88},{0x80,0x80,0x80,0x80,0x80,0x80,0xF8},{0x88,0xD8,0xA8,0x88,0x88,0x88,0x88},{0x88,0xC8,0xA8,0xA8,0x98,0x88,0x88},{0xF8,0x88,0x88,0x88,0x88,0x88,0xF8},{0xF0,0x88,0x88,0xF0,0x80,0x80,0x80},{0x70,0x88,0x88,0xA8,0xA8,0x90,0x68},{0xF0,0x88,0x88,0xF0,0x90,0x90,0x88},{0x70,0x88,0x80,0x70,0x08,0x88,0x70},{0xF8,0x20,0x20,0x20,0x20,0x20,0x20},{0x88,0x88,0x88,0x88,0x88,0x88,0x70},{0x88,0x88,0x88,0x88,0x88,0x50,0x20},{0x88,0x88,0x88,0x88,0xA8,0xD8,0x88},{0x88,0x88,0x50,0x20,0x50,0x88,0x88},{0x88,0x88,0x50,0x20,0x20,0x20,0x20},{0xF8,0x08,0x10,0x20,0x40,0x80,0xF8},{0x70,0x40,0x40,0x40,0x40,0x40,0x70},{0x00,0x80,0x40,0x20,0x10,0x08,0x00},{0x70,0x10,0x10,0x10,0x10,0x10,0x70},{0x20,0x70,0xA8,0x20,0x20,0x20,0x00},{0x00,0x20,0x40,0xF8,0x40,0x20,0x00},{0x00,0x20,0x20,0x20,0xA8,0x70,0x20},{0x00,0x20,0x10,0xF8,0x10,0x20,0x00},{0x00,0x88,0x50,0x20,0x50,0x88,0x00},{0x00,0x20,0x00,0xF8,0x00,0x20,0x00}};
|
||||||
|
|
||||||
const char SMLFONT[HICHAR-LOCHAR+1][5] = {/*{count:68,w:5,h:5,brev:1}*/
|
const char SMLFONT[HICHAR-LOCHAR+1][5] = {/*{count:68,w:5,h:5,brev:1}*/
|
||||||
{ 0x00,0x00,0x00,0x00,0x00 },{ 0x40,0x40,0x00,0x40,0x00 },{ 0xA0,0xA0,0x00,0x00,0x00 },{ 0x60,0xF0,0xF0,0x60,0x00 },{ 0x40,0xE0,0xE0,0x40,0x00 },{ 0x90,0x20,0x40,0x90,0x00 },{ 0xC0,0xB0,0xE0,0xD0,0x00 },{ 0x20,0x40,0x00,0x00,0x00 },{ 0x20,0x40,0x40,0x20,0x00 },{ 0x40,0x20,0x20,0x40,0x00 },{ 0x40,0xE0,0x40,0xA0,0x00 },{ 0x00,0x40,0xE0,0x40,0x00 },{ 0x00,0x00,0x00,0x60,0x20 },{ 0x00,0x00,0xE0,0x00,0x00 },{ 0x00,0x00,0x00,0x40,0x00 },{ 0x20,0x20,0x40,0x40,0x00 },{ 0xE0,0xA0,0xA0,0xE0,0x00 },{ 0xC0,0x40,0x40,0xE0,0x00 },{ 0xE0,0x20,0xC0,0xE0,0x00 },{ 0xE0,0x60,0x20,0xE0,0x00 },{ 0xA0,0xA0,0xE0,0x20,0x00 },{ 0xE0,0xC0,0x20,0xE0,0x00 },{ 0xC0,0x80,0xE0,0xE0,0x00 },{ 0xE0,0x20,0x40,0x40,0x00 },{ 0x60,0xE0,0xA0,0xE0,0x00 },{ 0xE0,0xE0,0x20,0x60,0x00 },{ 0x00,0x40,0x00,0x40,0x00 },{ 0x00,0x40,0x00,0x60,0x20 },{ 0x00,0x20,0x40,0x20,0x00 },{ 0x00,0xE0,0x00,0xE0,0x00 },{ 0x00,0x40,0x20,0x40,0x00 },{ 0xE0,0x20,0x60,0x00,0x40 },{ 0xF0,0x90,0x10,0xD0,0xF0 },{ 0x60,0xA0,0xE0,0xA0,0x00 },{ 0xC0,0xE0,0xA0,0xE0,0x00 },{ 0x60,0x80,0x80,0xE0,0x00 },{ 0xC0,0xA0,0xA0,0xC0,0x00 },{ 0xE0,0xC0,0x80,0xE0,0x00 },{ 0xE0,0xC0,0x80,0x80,0x00 },{ 0x60,0x80,0xA0,0xE0,0x00 },{ 0xA0,0xA0,0xE0,0xA0,0x00 },{ 0xE0,0x40,0x40,0xE0,0x00 },{ 0x60,0x20,0xA0,0xE0,0x00 },{ 0xA0,0xC0,0xC0,0xA0,0x00 },{ 0x80,0x80,0x80,0xE0,0x00 },{ 0xE0,0xE0,0xE0,0xA0,0x00 },{ 0xE0,0xA0,0xA0,0xA0,0x00 },{ 0xE0,0xA0,0xA0,0xE0,0x00 },{ 0xE0,0xA0,0xE0,0x80,0x00 },{ 0xE0,0xA0,0xE0,0xF0,0x00 },{ 0xE0,0xA0,0xC0,0xA0,0x00 },{ 0xE0,0x80,0x60,0xE0,0x00 },{ 0xE0,0x40,0x40,0x40,0x00 },{ 0xA0,0xA0,0xA0,0xE0,0x00 },{ 0xA0,0xA0,0xC0,0x80,0x00 },{ 0xA0,0xE0,0xE0,0xE0,0x00 },{ 0xA0,0x40,0xA0,0xA0,0x00 },{ 0xA0,0xE0,0x40,0x40,0x00 },{ 0xE0,0x20,0x40,0xE0,0x00 },{ 0x60,0x40,0x40,0x60,0x00 },{ 0x40,0x40,0x20,0x20,0x00 },{ 0x60,0x20,0x20,0x60,0x00 },{ 0x40,0xA0,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0xF0 },{ 0x80,0x40,0x00,0x00,0x00 },{ 0x00,0x60,0xA0,0xE0,0x00 },{ 0x80,0xE0,0xA0,0xE0,0x00 },{ 0x00,0x60,0x80,0xE0,0x00 }};
|
{ 0x00,0x00,0x00,0x00,0x00 },{ 0x40,0x40,0x00,0x40,0x00 },{ 0xA0,0xA0,0x00,0x00,0x00 },{ 0x60,0xF0,0xF0,0x60,0x00 },{ 0x40,0xE0,0xE0,0x40,0x00 },{ 0x90,0x20,0x40,0x90,0x00 },{ 0xC0,0xB0,0xE0,0xD0,0x00 },{ 0x20,0x40,0x00,0x00,0x00 },{ 0x20,0x40,0x40,0x20,0x00 },{ 0x40,0x20,0x20,0x40,0x00 },{ 0x40,0xE0,0x40,0xA0,0x00 },{ 0x00,0x40,0xE0,0x40,0x00 },{ 0x00,0x00,0x00,0x60,0x20 },{ 0x00,0x00,0xE0,0x00,0x00 },{ 0x00,0x00,0x00,0x40,0x00 },{ 0x20,0x20,0x40,0x40,0x00 },{ 0xE0,0xA0,0xA0,0xA0,0xE0 },{ 0xC0,0x40,0x40,0x40,0xE0 },{ 0xE0,0x20,0xE0,0x80,0xE0 },{ 0xE0,0x20,0x60,0x20,0xE0 },{ 0xA0,0xA0,0xE0,0x20,0x20 },{ 0xE0,0x80,0xE0,0x20,0xE0 },{ 0xE0,0x80,0xE0,0xA0,0xE0 },{ 0xE0,0x20,0x40,0x40,0x40 },{ 0xE0,0xA0,0xE0,0xA0,0xE0 },{ 0xE0,0xA0,0xE0,0x20,0xE0 },{ 0x00,0x40,0x00,0x40,0x00 },{ 0x00,0x40,0x00,0x60,0x20 },{ 0x00,0x20,0x40,0x20,0x00 },{ 0x00,0xE0,0x00,0xE0,0x00 },{ 0x00,0x40,0x20,0x40,0x00 },{ 0xE0,0x20,0x60,0x00,0x40 },{ 0xF0,0x90,0x10,0xD0,0xF0 },{ 0x60,0xA0,0xE0,0xA0,0x00 },{ 0xC0,0xE0,0xA0,0xE0,0x00 },{ 0x60,0x80,0x80,0xE0,0x00 },{ 0xC0,0xA0,0xA0,0xC0,0x00 },{ 0xE0,0xC0,0x80,0xE0,0x00 },{ 0xE0,0xC0,0x80,0x80,0x00 },{ 0x60,0x80,0xA0,0xE0,0x00 },{ 0xA0,0xA0,0xE0,0xA0,0x00 },{ 0xE0,0x40,0x40,0xE0,0x00 },{ 0x60,0x20,0xA0,0xE0,0x00 },{ 0xA0,0xC0,0xC0,0xA0,0x00 },{ 0x80,0x80,0x80,0xE0,0x00 },{ 0xE0,0xE0,0xE0,0xA0,0x00 },{ 0xE0,0xA0,0xA0,0xA0,0x00 },{ 0xE0,0xA0,0xA0,0xE0,0x00 },{ 0xE0,0xA0,0xE0,0x80,0x00 },{ 0xE0,0xA0,0xE0,0xF0,0x00 },{ 0xE0,0xA0,0xC0,0xA0,0x00 },{ 0xE0,0x80,0x60,0xE0,0x00 },{ 0xE0,0x40,0x40,0x40,0x00 },{ 0xA0,0xA0,0xA0,0xE0,0x00 },{ 0xA0,0xA0,0xC0,0x80,0x00 },{ 0xA0,0xE0,0xE0,0xE0,0x00 },{ 0xA0,0x40,0xA0,0xA0,0x00 },{ 0xA0,0xE0,0x40,0x40,0x00 },{ 0xE0,0x20,0x40,0xE0,0x00 },{ 0x60,0x40,0x40,0x60,0x00 },{ 0x40,0x40,0x20,0x20,0x00 },{ 0x60,0x20,0x20,0x60,0x00 },{ 0x40,0xA0,0x00,0x00,0x00 },{ 0x00,0x00,0x00,0x00,0xF0 },{ 0x80,0x40,0x00,0x00,0x00 },{ 0x00,0x60,0xA0,0xE0,0x00 },{ 0x80,0xE0,0xA0,0xE0,0x00 },{ 0x00,0x60,0x80,0xE0,0x00 }};
|
||||||
|
|
||||||
// draw a letter
|
// draw a letter
|
||||||
void draw_char(const FontDescriptor* font, byte ch, byte x, byte y, byte op) {
|
byte draw_char(const FontDescriptor* font, byte ch, byte x, byte y, byte op) {
|
||||||
const byte* src = font->chartab + (ch-font->base_ch)*font->pattern_y;
|
const byte* src = font->chartab + (ch-font->base_ch)*font->pattern_y;
|
||||||
byte xb = x>>2; // divide x by 4
|
byte* dest = &vmagic[y][x>>2];// destination address
|
||||||
byte* dest = &vmagic[y][xb]; // destination address
|
byte magic = M_SHIFT(x) | M_XPAND | (op & 0x30);
|
||||||
hw_magic = M_SHIFT(x) | M_XPAND | op;
|
// big sizes?
|
||||||
for (byte i=0; i<font->pattern_y; i++) {
|
if (op & 0xc0) {
|
||||||
char b = *src++;
|
char buf[8]; // expansion buffer
|
||||||
EXIT_CLIPDEST(dest);
|
char* mbuf = (buf - 0x4000);// make it magic
|
||||||
*dest++ = b; // expand lower nibble -> 1st byte
|
byte sc = 1 << (op >> 6); // 2x2 = 2, 4x4 = 4, 8x8 = 8
|
||||||
*dest++ = b; // expand upper nibble -> 2nd byte
|
for (byte i=0; i<font->pattern_y; i++) {
|
||||||
*dest++ = 0; // leftover -> 3rd byte
|
// expand into magic buffer onto stack
|
||||||
*dest = 0; // reset upper/lower flag
|
hw_magic = M_XPAND;
|
||||||
dest += VBWIDTH-3; // we incremented 3 bytes for this line
|
hw_xpand = 0b1100; // on = 11, off = 00
|
||||||
|
// 2x2 size
|
||||||
|
mbuf[1] = mbuf[0] = *src++;
|
||||||
|
// 4x4 size
|
||||||
|
if (op & 0x80) {
|
||||||
|
byte b = buf[0];
|
||||||
|
mbuf[3] = mbuf[2] = buf[1];
|
||||||
|
mbuf[1] = mbuf[0] = b;
|
||||||
|
}
|
||||||
|
// 8x8 size
|
||||||
|
if ((op & 0xc0) == 0xc0) {
|
||||||
|
byte b = buf[0];
|
||||||
|
mbuf[7] = mbuf[6] = buf[3];
|
||||||
|
mbuf[5] = mbuf[4] = buf[2];
|
||||||
|
mbuf[3] = mbuf[2] = buf[1];
|
||||||
|
mbuf[1] = mbuf[0] = b;
|
||||||
|
}
|
||||||
|
// draw to screen (magic, again)
|
||||||
|
hw_xpand = op & 0xf;
|
||||||
|
for (byte j=0; j<sc; j++) {
|
||||||
|
hw_magic = magic; // reset flip flop
|
||||||
|
EXIT_CLIPDEST(dest);
|
||||||
|
for (byte k=0; k<sc; k++) {
|
||||||
|
byte b = buf[k];
|
||||||
|
*dest++ = b;
|
||||||
|
*dest++ = b;
|
||||||
|
}
|
||||||
|
dest += VBWIDTH-sc*2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hw_xpand = op & 0xf;
|
||||||
|
for (byte i=0; i<font->pattern_y; i++) {
|
||||||
|
char b = *src++;
|
||||||
|
EXIT_CLIPDEST(dest);
|
||||||
|
hw_magic = magic; // reset flip flop
|
||||||
|
*dest++ = b; // expand lower nibble -> 1st byte
|
||||||
|
*dest++ = b; // expand upper nibble -> 2nd byte
|
||||||
|
*dest++ = 0; // leftover -> 3rd byte
|
||||||
|
dest += VBWIDTH-3; // we incremented 3 bytes for this line
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return font->frame_x << (op >> 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FONT_IX ((const FontDescriptor*)ctx->regs.w.ix)
|
#define FONT_IX ((const FontDescriptor*)ctx->regs.w.ix)
|
||||||
@ -364,17 +456,15 @@ void draw_string(ContextBlock *ctx, const char* str, byte x, byte y, byte op) {
|
|||||||
do {
|
do {
|
||||||
byte ch = *str++;
|
byte ch = *str++;
|
||||||
if (!ch) {
|
if (!ch) {
|
||||||
ctx->regs.b.e = x;
|
_E = x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ch < 0x20) {
|
if (ch < 0x20) {
|
||||||
x += 8 * ch;
|
x += draw_char(&FNTSYS, ' ', x, y, op); // TODO
|
||||||
} else if (ch < 0x64) {
|
} else if (ch < 0x64) {
|
||||||
draw_char(&FNTSYS, ch, x, y, op);
|
x += draw_char(&FNTSYS, ch, x, y, op);
|
||||||
x += 8;
|
|
||||||
} else if (ch >= 0x80) {
|
} else if (ch >= 0x80) {
|
||||||
draw_char(FONT_IX, ch, x, y, op);
|
x += draw_char(FONT_IX, ch, x, y, op);
|
||||||
x += FONT_IX->frame_x;
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
if (ch & 0x10) {
|
if (ch & 0x10) {
|
||||||
@ -382,11 +472,11 @@ void draw_string(ContextBlock *ctx, const char* str, byte x, byte y, byte op) {
|
|||||||
ctx->regs.b.ixh = *str++;
|
ctx->regs.b.ixh = *str++;
|
||||||
}
|
}
|
||||||
if (ch & 0x1)
|
if (ch & 0x1)
|
||||||
ctx->regs.b.e = *str++;
|
_E = *str++;
|
||||||
if (ch & 0x2)
|
if (ch & 0x2)
|
||||||
ctx->regs.b.d = *str++;
|
_D = *str++;
|
||||||
if (ch & 0x4)
|
if (ch & 0x4)
|
||||||
ctx->regs.b.c = *str++;
|
_C = *str++;
|
||||||
*/
|
*/
|
||||||
// TODO: only can change font
|
// TODO: only can change font
|
||||||
}
|
}
|
||||||
@ -395,24 +485,23 @@ void draw_string(ContextBlock *ctx, const char* str, byte x, byte y, byte op) {
|
|||||||
|
|
||||||
// String display routine (pass pointer to string)
|
// String display routine (pass pointer to string)
|
||||||
void STRDIS2(ContextBlock *ctx, char *str) {
|
void STRDIS2(ContextBlock *ctx, char *str) {
|
||||||
byte opts = ctx->regs.b.c;
|
byte opts = _C;
|
||||||
byte x = ctx->regs.b.e;
|
byte x = _E;
|
||||||
byte y = ctx->regs.b.d;
|
byte y = _D;
|
||||||
void* fontdesc = (void*) ctx->regs.w.ix;
|
void* fontdesc = (void*) ctx->regs.w.ix;
|
||||||
hw_xpand = opts & 0xf;
|
draw_string(ctx, str, x, y, opts); // TODO: opts
|
||||||
draw_string(ctx, str, x, y, 3&(opts>>4)); // TODO: opts
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// String display routine
|
// String display routine
|
||||||
void STRDIS(ContextBlock *ctx) {
|
void STRDIS(ContextBlock *ctx) {
|
||||||
char* str = (char*) ctx->regs.w.hl;
|
char* str = (char*) _HL;
|
||||||
STRDIS2(ctx, str);
|
STRDIS2(ctx, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Character display routine
|
// Character display routine
|
||||||
void CHRDIS(ContextBlock *ctx) {
|
void CHRDIS(ContextBlock *ctx) {
|
||||||
char chstr[2];
|
char chstr[2];
|
||||||
chstr[0] = ctx->regs.b.a;
|
chstr[0] = _A;
|
||||||
chstr[1] = 0;
|
chstr[1] = 0;
|
||||||
STRDIS2(ctx, chstr);
|
STRDIS2(ctx, chstr);
|
||||||
}
|
}
|
||||||
@ -420,15 +509,29 @@ void CHRDIS(ContextBlock *ctx) {
|
|||||||
// BCD routine
|
// BCD routine
|
||||||
const char BCDTAB[17] = "0123456789*+,-./";
|
const char BCDTAB[17] = "0123456789*+,-./";
|
||||||
|
|
||||||
|
// DISNUM - (E.D) x/y (C) options (B) ext (HL) BCD-addr
|
||||||
void DISNUM(ContextBlock *ctx) {
|
void DISNUM(ContextBlock *ctx) {
|
||||||
// TODO: options, B
|
// TODO: options, B
|
||||||
word oldhl = ctx->regs.w.hl;
|
byte x = _E;
|
||||||
byte val = *(byte*) oldhl;
|
byte y = _D;
|
||||||
char bcdstr[3];
|
byte opt = _C;
|
||||||
bcdstr[0] = BCDTAB[val >> 4];
|
byte ext = _B;
|
||||||
bcdstr[1] = BCDTAB[val & 15];
|
byte ndigits = ext & 63;
|
||||||
bcdstr[2] = 0;
|
const FontDescriptor* font = (ext&64) ? &FNTSML : &FNTSYS;
|
||||||
STRDIS2(ctx, bcdstr);
|
byte add = (ext&64) ? 128 : 0;
|
||||||
|
byte noleadingzero = ext & 128;
|
||||||
|
byte* pbcd = (byte*) _HL;
|
||||||
|
pbcd += (ndigits-1)/2;
|
||||||
|
while (ndigits--) {
|
||||||
|
byte val = *pbcd;
|
||||||
|
if (ndigits & 1) {
|
||||||
|
val >>= 4;
|
||||||
|
} else {
|
||||||
|
val &= 15;
|
||||||
|
pbcd--;
|
||||||
|
}
|
||||||
|
x += draw_char(font, BCDTAB[val]+add, x, y, opt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -436,7 +539,58 @@ typedef struct {
|
|||||||
byte xsize, ysize;
|
byte xsize, ysize;
|
||||||
byte pattern[0];
|
byte pattern[0];
|
||||||
} PatternBlock;
|
} PatternBlock;
|
||||||
// TODO
|
|
||||||
|
// write pattern (E,D,C,B) magic A @ HL
|
||||||
|
void WRIT(ContextBlock *ctx) {
|
||||||
|
byte x = _E;
|
||||||
|
byte y = _D;
|
||||||
|
byte w = _C;
|
||||||
|
byte h = _B;
|
||||||
|
byte* src = (byte*) _HL;
|
||||||
|
byte* dest = &vmagic[y][x>>2];// destination address
|
||||||
|
byte i,j;
|
||||||
|
byte magic = _A;
|
||||||
|
for (j=0; j<h; j++) {
|
||||||
|
EXIT_CLIPDEST(dest);
|
||||||
|
if ((hw_magic = magic) & M_XPAND) {
|
||||||
|
for (i=0; i<w; i++) {
|
||||||
|
byte b = *src++;
|
||||||
|
*dest++ = b;
|
||||||
|
*dest++ = b;
|
||||||
|
}
|
||||||
|
*dest = 0;
|
||||||
|
dest += VBWIDTH-w*2;
|
||||||
|
} else {
|
||||||
|
for (i=0; i<w; i++) {
|
||||||
|
*dest++ = *src++;
|
||||||
|
}
|
||||||
|
*dest = 0;
|
||||||
|
dest += VBWIDTH-w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write sized pattern (E,D) magic A @ HL
|
||||||
|
void WRITP(ContextBlock *ctx) {
|
||||||
|
byte* src = (byte*) _HL;
|
||||||
|
// get size
|
||||||
|
_C = *src++;
|
||||||
|
_B = *src++;
|
||||||
|
// update src
|
||||||
|
_HL = (word) src;
|
||||||
|
WRIT(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write relative pattern (E,D) magic A @ HL
|
||||||
|
void WRITR(ContextBlock *ctx) {
|
||||||
|
byte* src = (byte*) _HL;
|
||||||
|
// sub offset
|
||||||
|
_E -= *src++;
|
||||||
|
_D -= *src++;
|
||||||
|
// update src
|
||||||
|
_HL = (word) src;
|
||||||
|
WRITP(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void wait_vsync() {
|
void wait_vsync() {
|
||||||
byte x = TMR60;
|
byte x = TMR60;
|
||||||
@ -444,22 +598,57 @@ void wait_vsync() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PAWS(ContextBlock *ctx) {
|
void PAWS(ContextBlock *ctx) {
|
||||||
while (ctx->regs.b.b--) {
|
while (_B--) {
|
||||||
wait_vsync();
|
wait_vsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MATH
|
// MATH
|
||||||
|
|
||||||
|
void MOVE(ContextBlock *ctx) {
|
||||||
|
byte* dest = (byte*) _DE;
|
||||||
|
const byte* src = (const byte*) _HL;
|
||||||
|
word nb = _BC;
|
||||||
|
memcpy(dest, src, nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
word bcdadd8(byte a, byte b, byte c) {
|
||||||
|
a;b;c;
|
||||||
|
__asm
|
||||||
|
ld a,6(ix) ; carry
|
||||||
|
rrc a ; set carry bit
|
||||||
|
ld h,#0 ; carry goes here
|
||||||
|
ld a,4(ix) ; a -> A
|
||||||
|
adc a,5(ix) ; a + b -> A
|
||||||
|
daa ; BCD conversion
|
||||||
|
ld l,a ; result -> L
|
||||||
|
rl h ; carry -> H
|
||||||
|
__endasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCDADD(ContextBlock *ctx) {
|
||||||
|
byte* dest = (byte*) _DE;
|
||||||
|
const byte* src = (const byte*) _HL;
|
||||||
|
byte n = _B;
|
||||||
|
byte carry = 0;
|
||||||
|
while (n--) {
|
||||||
|
byte a = *src++;
|
||||||
|
byte b = *dest;
|
||||||
|
word r = bcdadd8(a,b,carry);
|
||||||
|
carry = (r>>8);
|
||||||
|
*dest++ = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RANGED(ContextBlock *ctx) {
|
void RANGED(ContextBlock *ctx) {
|
||||||
/* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
|
/* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
|
||||||
RANSHT ^= RANSHT << 13;
|
RANSHT ^= RANSHT << 13;
|
||||||
RANSHT ^= RANSHT >> 17;
|
RANSHT ^= RANSHT >> 17;
|
||||||
RANSHT ^= RANSHT << 5;
|
RANSHT ^= RANSHT << 5;
|
||||||
if (ctx->regs.b.a == 0) {
|
if (_A == 0) {
|
||||||
ctx->regs.b.a = (byte)RANSHT;
|
_A = (byte)RANSHT;
|
||||||
} else {
|
} else {
|
||||||
ctx->regs.b.a = (byte)(RANSHT % ctx->regs.b.a);
|
_A = (byte)(RANSHT % _A);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,13 +670,13 @@ const SysCallEntry SYSCALL_TABLE[64] = {
|
|||||||
{ &SETOUT, REG_D|REG_B|REG_A },
|
{ &SETOUT, REG_D|REG_B|REG_A },
|
||||||
{ &COLSET, REG_HL },
|
{ &COLSET, REG_HL },
|
||||||
{ &FILL, REG_A|REG_BC|REG_DE },
|
{ &FILL, REG_A|REG_BC|REG_DE },
|
||||||
{ 0, 0 },
|
{ &RECTAN, REG_A|REG_B|REG_C|REG_D|REG_E },
|
||||||
/* 30 */
|
/* 30 */
|
||||||
{ 0, 0 },
|
{ /*&VWRITR*/0, 0 },
|
||||||
{ 0, 0 },
|
{ &WRITR, REG_E|REG_D|REG_A|REG_HL },
|
||||||
{ 0, 0 },
|
{ &WRITP, REG_E|REG_D|REG_A|REG_HL },
|
||||||
{ 0, 0 },
|
{ &WRIT, REG_E|REG_D|REG_C|REG_B|REG_A|REG_HL },
|
||||||
{ 0, 0 },
|
{ /*&WRITA*/0, 0 },
|
||||||
/* 40 */
|
/* 40 */
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
@ -497,7 +686,7 @@ const SysCallEntry SYSCALL_TABLE[64] = {
|
|||||||
/* 50 */
|
/* 50 */
|
||||||
{ &CHRDIS, REG_E|REG_D|REG_C|REG_A },
|
{ &CHRDIS, REG_E|REG_D|REG_C|REG_A },
|
||||||
{ &STRDIS, REG_E|REG_D|REG_C|REG_HL },
|
{ &STRDIS, REG_E|REG_D|REG_C|REG_HL },
|
||||||
{ &DISNUM, REG_E|REG_D|REG_C|REG_HL },
|
{ &DISNUM, REG_E|REG_D|REG_C|REG_B|REG_HL },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
/* 60 */
|
/* 60 */
|
||||||
@ -521,9 +710,9 @@ const SysCallEntry SYSCALL_TABLE[64] = {
|
|||||||
/* 90 */
|
/* 90 */
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
{ &MOVE, REG_DE|REG_BC|REG_HL },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ &BCDADD, REG_DE|REG_B|REG_HL },
|
||||||
{ 0, 0 },
|
|
||||||
/* 100 */
|
/* 100 */
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
@ -566,66 +755,34 @@ void SYSCALL(ContextBlock *ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
void bios_init() {
|
||||||
void main() {
|
memset((void*)0x4fce, 0, 0x5000-0x4fce);
|
||||||
__asm
|
ACTINT(0);
|
||||||
LD SP,#0x4fce ; position stack below BIOS vars
|
hw_verbl = 96*2;
|
||||||
ld hl,#0x20d
|
hw_horcb = 41;
|
||||||
push hl
|
hw_inmod = 0x8;
|
||||||
pop ix
|
// clear shifter
|
||||||
RST 0x38
|
hw_magic = 0;
|
||||||
.db 0 ; INTPC
|
*((byte*)0x4fce) = 0;
|
||||||
.db 22+1 ; SETOUT
|
hw_magic = 0;
|
||||||
.db 102*2, 0x1c, 0x08
|
|
||||||
.db 14 ; ACTINT
|
|
||||||
.db 24+1 ; COLSET
|
|
||||||
.dw _main ; palette???
|
|
||||||
.db 26+1 ; FILL
|
|
||||||
.dw 0x4000
|
|
||||||
.dw 90*40
|
|
||||||
.db 0xaa
|
|
||||||
.db 52+1 ; draw string
|
|
||||||
.db 0
|
|
||||||
.db 32
|
|
||||||
.db 0x0c
|
|
||||||
.dw HelloString
|
|
||||||
.db 52+1 ; draw string
|
|
||||||
.db 0
|
|
||||||
.db 48
|
|
||||||
.db 0x0c
|
|
||||||
.dw HelloString
|
|
||||||
.db 50+1 ; draw char
|
|
||||||
.db 0
|
|
||||||
.db 64
|
|
||||||
.db 0x0c
|
|
||||||
.db 0x40
|
|
||||||
.db 2 ; EXIT
|
|
||||||
.loop:
|
|
||||||
ld hl,#0x4FED
|
|
||||||
ld a,(hl)
|
|
||||||
add a,#0x30
|
|
||||||
RST 0x38
|
|
||||||
.db 50 ; draw char
|
|
||||||
jp .loop
|
|
||||||
HelloString:
|
|
||||||
.ascii "HELLO WORLD! "
|
|
||||||
.db 0xc1, 0xc2, 0xc3, 0xc4, 0xc5
|
|
||||||
.db 0
|
|
||||||
; Critter Pattern
|
|
||||||
; Color 0 = White and Color 2 = Black
|
|
||||||
;
|
|
||||||
PATERN: .DB 0,0 ; (0,0) Position
|
|
||||||
.DB 0x02,0x08 ; 2 byte, 8 line pattern size
|
|
||||||
|
|
||||||
.DB 0x0A,0xA0 ; 0000101010100000 - . . 2 2 2 2 . .
|
|
||||||
.DB 0x22,0x88 ; 0010001010001000 - . 2 . 2 2 . 2 .
|
|
||||||
.DB 0xAA,0xAA ; 1010101010101010 - 2 2 2 2 2 2 2 2
|
|
||||||
.DB 0x2A,0xA8 ; 0010101010101000 - . 2 2 2 2 2 2 .
|
|
||||||
.DB 0x08,0x20 ; 0000100000100000 - . . 2 . . 2 . .
|
|
||||||
.DB 0x20,0x08 ; 0010000000001000 - . 2 . . . . 2 .
|
|
||||||
.DB 0x08,0x20 ; 0000100000100000 - . . 2 . . 2 . .
|
|
||||||
.DB 0x00,0x00 ; 0000000000000000 - . . . . . . . .
|
|
||||||
__endasm;
|
|
||||||
while (1) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
void _main() {
|
||||||
|
__asm
|
||||||
|
#include "astrocade.inc"
|
||||||
|
#include "test3.s"
|
||||||
|
__endasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void _biosend() __naked {
|
||||||
|
__asm
|
||||||
|
; eat up rest of space
|
||||||
|
.ds 0x2000 - (. - __biosend)
|
||||||
|
__endasm;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
;#link "bioslib.c"
|
||||||
|
|
||||||
.module biosasm
|
.module biosasm
|
||||||
.globl _STIMER,_CTIMER,_BIGFONT,_SMLFONT
|
.globl _STIMER,_CTIMER,_BIGFONT,_SMLFONT
|
||||||
|
|
||||||
@ -93,3 +95,4 @@ ReloadRegs:
|
|||||||
pop hl
|
pop hl
|
||||||
pop bc
|
pop bc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
125
presets/astrocade-bios/test1.s
Normal file
125
presets/astrocade-bios/test1.s
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
|
||||||
|
|
||||||
|
.globl _main
|
||||||
|
_main:
|
||||||
|
LD SP,#0x4fce ; position stack below BIOS vars
|
||||||
|
ld hl,#0x20d ; small font -> IX
|
||||||
|
push hl
|
||||||
|
pop ix
|
||||||
|
SYSTEM INTPC
|
||||||
|
DO SETOUT
|
||||||
|
.db 89*2, 23, 0x00
|
||||||
|
DONT ACTINT
|
||||||
|
DO COLSET
|
||||||
|
.dw palette
|
||||||
|
DO FILL
|
||||||
|
.dw 0x4000
|
||||||
|
.dw 95*40
|
||||||
|
.db 0x00
|
||||||
|
DO STRDIS
|
||||||
|
.db 2
|
||||||
|
.db 2
|
||||||
|
.db (1<<2)
|
||||||
|
.dw HelloString
|
||||||
|
DO STRDIS
|
||||||
|
.db 4
|
||||||
|
.db 16
|
||||||
|
.db (2<<2)|0x40
|
||||||
|
.dw BigString
|
||||||
|
DO STRDIS ; draw string
|
||||||
|
.db 4 ; x
|
||||||
|
.db 36 ; y
|
||||||
|
.db (2<<2)|0x80 ; options
|
||||||
|
.dw FourString
|
||||||
|
DO CHRDIS ; draw char
|
||||||
|
.db 109
|
||||||
|
.db 24
|
||||||
|
.db (3<<2)|0x20|0xc0 ; xor 8x8
|
||||||
|
.db 0x3f
|
||||||
|
DO STRDIS
|
||||||
|
.db 4
|
||||||
|
.db 80
|
||||||
|
.db (1<<2)
|
||||||
|
.dw NumString
|
||||||
|
DO RECTAN
|
||||||
|
.db 4
|
||||||
|
.db 72
|
||||||
|
.db 100
|
||||||
|
.db 4
|
||||||
|
.db 0xa5
|
||||||
|
DO WRITR
|
||||||
|
.db 50
|
||||||
|
.db 80
|
||||||
|
.db 0x00
|
||||||
|
.dw PATERN
|
||||||
|
DO WRITR
|
||||||
|
.db 67
|
||||||
|
.db 80
|
||||||
|
.db 0x08|1 ;expand
|
||||||
|
.dw BALL
|
||||||
|
DO MOVE
|
||||||
|
.dw BCDNUM
|
||||||
|
.dw 3
|
||||||
|
.dw _BCDNUM
|
||||||
|
; exit interpreter
|
||||||
|
DONT XINTC
|
||||||
|
.loop:
|
||||||
|
SYSSUK DISNUM
|
||||||
|
.db 80
|
||||||
|
.db 80
|
||||||
|
.db (2<<2) ;opts
|
||||||
|
.db 6|0x40|0x80 ;ext
|
||||||
|
.dw BCDNUM
|
||||||
|
SYSSUK PAWS
|
||||||
|
.db 60
|
||||||
|
SYSSUK BCDADD
|
||||||
|
.dw BCDNUM
|
||||||
|
.db 3
|
||||||
|
.dw BCDINC
|
||||||
|
jp .loop
|
||||||
|
HelloString:
|
||||||
|
.ascii "HELLO WORLD! "
|
||||||
|
.db 0xb1, 0xb2, 0xb3, 0xb4, 0xb5
|
||||||
|
.db 0
|
||||||
|
BigString:
|
||||||
|
.ascii "BIG TEXT!"
|
||||||
|
.db 0
|
||||||
|
FourString:
|
||||||
|
.ascii "4X4"
|
||||||
|
.db 0
|
||||||
|
NumString:
|
||||||
|
.db 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9
|
||||||
|
.db 0
|
||||||
|
palette:
|
||||||
|
.db 0x77, 0xD4, 0x35, 0x01
|
||||||
|
.db 0x07, 0xD4, 0x35, 0x01
|
||||||
|
|
||||||
|
BCDNUM = 0x4ea0 ; RAM
|
||||||
|
_BCDNUM:
|
||||||
|
.db 0x97,0x34,0x12
|
||||||
|
BCDINC:
|
||||||
|
.db 0x01,0x00,0x00
|
||||||
|
; Critter Pattern
|
||||||
|
; Color 0 = White and Color 2 = Black
|
||||||
|
;
|
||||||
|
PATERN: .DB 0,0 ; (0,0) Position
|
||||||
|
.DB 0x02,0x08 ; 2 byte, 8 line pattern size
|
||||||
|
|
||||||
|
.DB 0x0A,0xA0 ; 0000101010100000 - . . 2 2 2 2 . .
|
||||||
|
.DB 0x22,0x88 ; 0010001010001000 - . 2 . 2 2 . 2 .
|
||||||
|
.DB 0xAA,0xAA ; 1010101010101010 - 2 2 2 2 2 2 2 2
|
||||||
|
.DB 0x2A,0xA8 ; 0010101010101000 - . 2 2 2 2 2 2 .
|
||||||
|
.DB 0x08,0x20 ; 0000100000100000 - . . 2 . . 2 . .
|
||||||
|
.DB 0x20,0x08 ; 0010000000001000 - . 2 . . . . 2 .
|
||||||
|
.DB 0x08,0x20 ; 0000100000100000 - . . 2 . . 2 . .
|
||||||
|
.DB 0x00,0x00 ; 0000000000000000 - . . . . . . . .
|
||||||
|
|
||||||
|
BALL: .db 0,0
|
||||||
|
.db 1,6
|
||||||
|
.db 0b01111010
|
||||||
|
.db 0b11011101
|
||||||
|
.db 0b10111101
|
||||||
|
.db 0b10111101
|
||||||
|
.db 0b11111101
|
||||||
|
.db 0b01111010
|
||||||
|
|
Loading…
Reference in New Issue
Block a user