2019-07-17 13:52:26 +00:00
|
|
|
; SIM8800
|
|
|
|
; Altair 8800 simulator by Charles Mangin, 2019
|
|
|
|
;8080 emulator code:
|
|
|
|
; APPLE-80 - an 8080 simulator-debug package Copyright (c) 1979 by Dann Mccreary
|
|
|
|
|
|
|
|
DSK SIM8800
|
|
|
|
ORG $9000
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
2019-10-11 01:27:34 +00:00
|
|
|
; TODO:
|
|
|
|
; optimize for speed, 65C02 - target is Enhanced IIe, 128K RAM
|
|
|
|
; port to 65816? 24bit addresses, 16 bit registers, 64k contiguous AUX, 2.8mhz
|
2019-10-11 01:20:30 +00:00
|
|
|
;
|
2019-07-17 13:52:26 +00:00
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ZERO EQU $00
|
|
|
|
SPEED EQU $02 ; ???
|
|
|
|
INTE EQU $03 ; INTERRUPT ENABLE - 00 == interrupts enabled, 01 == no interrupts
|
|
|
|
PSW EQU $04 ; PROCESSOR STATUS
|
|
|
|
SIMA EQU $05 ; ACCUMULATOR
|
|
|
|
SIMM EQU $06 ; DUMMY MEMORY REGISTER
|
|
|
|
SIML EQU $07 ; HL REG PAIR
|
|
|
|
SIMH EQU $08 ; HL REG PAIR
|
|
|
|
SIME EQU $09 ; DE REG PAIR
|
|
|
|
SIMD EQU $0A ; DE REG PAIR
|
|
|
|
SIMC EQU $0B ; BC REG PAIR
|
|
|
|
SIMB EQU $0C ; BC REG PAIR
|
|
|
|
SPL EQU $0D ; STACK POINTER L
|
|
|
|
SPH EQU $0E ; STACK POINTER H
|
|
|
|
PCL EQU $0F ; 8080 PROGRAM COUNTER L
|
|
|
|
PCH EQU $10 ; 8080 PROGRAM COUNTER H
|
|
|
|
DECIT EQU $11 ; DOUBLE PRECISION -1
|
|
|
|
INCIT EQU $13 ; DOUBLE PRECISION 0001
|
|
|
|
FLAG EQU $15 ; USED BY SIMULATOR
|
|
|
|
DESTDA EQU $16 ; DESTINATION DATA
|
|
|
|
DEST EQU $17 ; DESTINATION INDEX
|
|
|
|
SRC EQU $18 ; SOURCE INDEX
|
|
|
|
|
|
|
|
OPCODE EQU $1A ; CURRENT OPCODE
|
|
|
|
;PSPEED EQU $1B ; TRACE SPEED FROM PADDLE0
|
|
|
|
PNT EQU $1C ; DATA POINTER
|
|
|
|
SCR EQU $1E ; SCRATCHPAD REGISTER
|
|
|
|
|
|
|
|
TEXTTOP EQU $22 ; text window top edge
|
|
|
|
|
|
|
|
HPOS EQU $24 ; HORIZONTAL CURSOR POSITION
|
|
|
|
VPOS EQU $25 ; VERTICAL CURSOR POSITION
|
|
|
|
CURPOS EQU $28 ; CURSOR POSITION ADDRESS
|
|
|
|
KSWL EQU $38 ; keyboard input routine
|
|
|
|
KSWH EQU $39 ; normally $FD1B
|
|
|
|
|
|
|
|
HIPCH EQU $FE ; is the PC above 32k limit?
|
|
|
|
|
|
|
|
KBDBUF EQU $C000 ; KEYBOARD BUFFER
|
|
|
|
KBDSTROBE EQU $C010 ; KEYBOARD STROBE
|
|
|
|
SPKR EQU $C030 ; CLICK
|
|
|
|
LORES EQU $C050
|
|
|
|
TXTSET EQU $C051
|
|
|
|
MIXCLR EQU $C052
|
|
|
|
MIXSET EQU $C053
|
|
|
|
|
|
|
|
TXTPAGE1 EQU $C054
|
|
|
|
TXTPAGE2 EQU $C055
|
|
|
|
|
|
|
|
RAMRDOFF EQU $C002 ; Read enable main memory from $0200-$BFFF
|
|
|
|
RAMRDON EQU $C003 ; Read enable aux memory from $0200-$BFFF
|
|
|
|
RAMWRTOFF EQU $C004 ; Write enable main memory from $0200-$BFFF
|
|
|
|
RAMWRTON EQU $C005 ; Write enable aux memory from $0200-$BFFF
|
|
|
|
ALZTPOFF EQU $C008 ; Enable main memory from $0000-$01FF & avl BSR
|
|
|
|
ALTZPON EQU $C009 ; Enable aux memory from $0000-$01FF & avl BSR
|
|
|
|
|
|
|
|
; READ HIGH BIT:
|
|
|
|
RAMRD EQU $C013 ; 0=main $0200-$BFFF active reads 1=aux active
|
|
|
|
RAMWRT EQU $C014 ; 0=main $0200-$BFFF active writes 1=aux writes
|
|
|
|
ALTZP EQU $C016 ; 1=aux $0000-$1FF+auxBSR 0=main available
|
|
|
|
|
|
|
|
AUXMOVE EQU $C311 ;
|
|
|
|
; The beginning address of the block to be moved must be stored at locations A1L ($3C) and A1H ($3D) and the ending address at
|
|
|
|
; A2L ($3E) and A2H ($3F). Finally, the destination address must be stored at A4L ($42) and A4H ($43).
|
|
|
|
; If the carry flag is set, then the move will be performed from main memory to auxiliary memory.
|
|
|
|
; If it is clear, the move will take place in the opposite direction.
|
|
|
|
|
|
|
|
|
|
|
|
CLRLORES EQU $F832 ; clear low res screen
|
|
|
|
PREAD EQU $FB1E ; PREAD returns a number that represents the position of a hand control.
|
|
|
|
SETTXT EQU $FB39 ; Set Text Mode
|
|
|
|
SETGR EQU $FB40 ; mixed text/graphics Mode
|
|
|
|
BASCALC EQU $FBC1 ; calculate base address
|
|
|
|
BELL2 EQU $FBE4 ; 60hz bell
|
|
|
|
VTAB EQU $FC22 ; Sets the cursor vertical position (from CV)
|
|
|
|
HOME EQU $FC58 ; HOME
|
|
|
|
CLREOL EQU $FC9C ; say end of line
|
|
|
|
WAIT EQU $FCA8 ; simple delay
|
|
|
|
KEYIN EQU $FD1B
|
|
|
|
RDKEY EQU $FD0C ; read keyboard input
|
|
|
|
|
|
|
|
CROUT EQU $FD8E ; Print CR
|
|
|
|
PRBYTE EQU $FDDA ; Prints byte as 2 hex digits
|
|
|
|
COUT EQU $FDED ; character output
|
|
|
|
BELL EQU $FF3A ; outputs ^G
|
|
|
|
OLDRST EQU $FF59 ; set screen mode and init
|
|
|
|
|
|
|
|
MLI EQU $BF00 ; ProDOS system call
|
|
|
|
OPENCMD EQU $C8 ; OPEN command index
|
|
|
|
READCMD EQU $CA ; READ command index
|
|
|
|
SET_MARKCMD EQU $CE ; SET_MARK index
|
|
|
|
CLOSECMD EQU $CC ; CLOSE command index
|
|
|
|
WRITECMD EQU $CB ; HERE THERE BE DRAGONS
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
; DO AUXMOVE from $9000 to $B000 -> aux $9000
|
|
|
|
LDA #$00
|
|
|
|
STA $3C
|
|
|
|
STA $3E
|
|
|
|
STA $42
|
|
|
|
LDA #$90
|
|
|
|
STA $3D
|
|
|
|
STA $43
|
|
|
|
LDA #$B0
|
|
|
|
STA $3F
|
|
|
|
SEC
|
|
|
|
JSR AUXMOVE
|
|
|
|
; magic done.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JSR HOME
|
|
|
|
JSR CHOOSER ; determine what program/basic/bootloader to load
|
|
|
|
|
|
|
|
JSR LOADPROGRAM ; load it, based on ACC value
|
|
|
|
|
|
|
|
JSR HOME
|
|
|
|
JSR INSTRUCTIONS ; copyright and instructions
|
|
|
|
|
|
|
|
JSR ALTAIRSCREEN ; Draw GR screen
|
|
|
|
|
|
|
|
; INIT
|
|
|
|
INIT JMP SETUP
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; MAIN
|
|
|
|
MNSTRT JMP DISPLAYLOOP ; setup and display first frame
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
SIM80 LDA #$00
|
|
|
|
STA HIPCH ; reset HIPCH for each go-round
|
|
|
|
; **** add $10 to PCH
|
|
|
|
LDA PCH
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
CMP #$7F ; above 32k limit?
|
|
|
|
BCC ADC10
|
|
|
|
ROL HIPCH ; carry into HIPCH indicates we schlepped above 32K
|
|
|
|
SEC ; gotta set carry again.
|
|
|
|
SBC #$80 ; subtract #$80 - probably could do AND 7F
|
|
|
|
CLC
|
|
|
|
|
|
|
|
ADC10 ADC #$10
|
|
|
|
STA PCH
|
|
|
|
; ****
|
|
|
|
|
|
|
|
JSR MAIN ; execute OPCODE
|
|
|
|
|
|
|
|
; **** subtract $10 from PCH
|
|
|
|
SEC
|
|
|
|
LDA PCH
|
|
|
|
SBC #$10
|
|
|
|
|
|
|
|
LDX HIPCH ; were we reading PC from AUX?
|
|
|
|
BEQ SBC10 ; nope, skip
|
|
|
|
CLC
|
|
|
|
ADC #$80
|
|
|
|
ROR HIPCH ; HIPCH 1 into carry, leaving 00
|
|
|
|
SBC10 STA PCH ; store resulting PCH
|
|
|
|
;****
|
|
|
|
|
|
|
|
LDA PSW ; processor status
|
|
|
|
AND #$D7 ; AND 1101 0111 - clear MI and HLTA bits
|
|
|
|
ORA #$02 ; OR 0000 0010 - set WO bit
|
|
|
|
STA PSW ;
|
|
|
|
CLI ; clear interrupts
|
|
|
|
|
|
|
|
JSR SIMDSK ; operate virtual disk drive
|
|
|
|
|
|
|
|
RTS ; return
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; EXECUTE ONE 8080 OPCODE
|
|
|
|
MAIN SEI ; DON'T ALLOW INTERRUPTS
|
|
|
|
CLD ; CLEAR DECIMAL MODE
|
|
|
|
LDX #$00 ; LOAD INDEX
|
|
|
|
; **** add $10 to SIMH
|
|
|
|
CLC
|
|
|
|
LDA SIMH
|
|
|
|
|
|
|
|
; compare to 8f, subtract 80
|
|
|
|
|
|
|
|
CMP #$7F ; if it's >=32K boundary after add $10, get from AUX
|
|
|
|
BCC STASIMM2
|
|
|
|
STA RAMRDON ; set AUX READ
|
2019-10-11 01:27:34 +00:00
|
|
|
|
|
|
|
SBC #$80 ; subtract #$80
|
2019-07-17 13:52:26 +00:00
|
|
|
CLC ; read from AUX, still write to MAIN
|
|
|
|
; add #$80
|
|
|
|
; set MAIN READ
|
|
|
|
STASIMM2 ADC #$10
|
|
|
|
STA SIMH
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STASIMM LDA (SIML,X) ; FETCH MEMORY *** from (HL) register pair ***
|
|
|
|
STA SIMM ; crashes II if SIMH is C0 softswitch area
|
|
|
|
|
|
|
|
; **** subtract $10 from SIMH
|
|
|
|
DECSIMH SEC ; then subtract #$10... oof.
|
|
|
|
LDA SIMH
|
|
|
|
SBC #$10
|
|
|
|
STA SIMH
|
|
|
|
;****
|
|
|
|
|
|
|
|
LDA RAMRD ; if RAMRD high bit
|
|
|
|
BPL CHECKPCH ; low = RAMRDOFF
|
|
|
|
STA RAMRDOFF ; high = turn it off, etc
|
|
|
|
CLC ; add #$80 to SIMH again
|
|
|
|
LDA SIMH
|
2019-10-11 01:27:34 +00:00
|
|
|
|
|
|
|
ADC #$80
|
2019-07-17 13:52:26 +00:00
|
|
|
STA SIMH
|
|
|
|
|
|
|
|
CHECKPCH ; is PC looking above #$8FFF?
|
|
|
|
LDA HIPCH
|
|
|
|
BEQ LDAPC ; nope, skip
|
|
|
|
STA RAMRDON ; read from AUX
|
|
|
|
|
|
|
|
LDAPC LDA (PCL,X) ; FETCH INSTRUCTION **** this should come from real $1000-$8fff
|
|
|
|
|
|
|
|
PHA ; opcode to stack
|
|
|
|
LDA RAMRD ; if RAMRD high bit
|
|
|
|
BPL STAOPCODE
|
|
|
|
STA RAMRDOFF ; high = turn it off, etc
|
|
|
|
|
|
|
|
|
|
|
|
STAOPCODE PLA ; get the opcode back
|
|
|
|
|
|
|
|
STA OPCODE ;
|
|
|
|
EOR #$76 ;
|
|
|
|
TAX ;
|
|
|
|
LDY #$01 ;
|
|
|
|
LDA PNT ;
|
|
|
|
AND INTE ; IS THIS A HALT?
|
|
|
|
BPL CKINT ;
|
|
|
|
STY INTE ;
|
|
|
|
STY PNT ;
|
|
|
|
ORA #$C7 ;
|
|
|
|
STA OPCODE ;
|
|
|
|
DEY ;
|
|
|
|
; CHECK FOR INTERRUPT
|
|
|
|
CKINT LDA INTE ;
|
|
|
|
BNE NINT ;
|
|
|
|
DEC INTE ;
|
|
|
|
; ENABLE INTERRUPT
|
|
|
|
NINT TXA ;
|
|
|
|
BNE NOHLT ;
|
|
|
|
DEY ;
|
|
|
|
; HALT?
|
|
|
|
NOHLT TYA ;
|
|
|
|
BEQ ITR ;
|
|
|
|
JSR INCPC ;
|
|
|
|
; SET COUNTER/INDEX
|
|
|
|
ITR LDX #$02 ;
|
|
|
|
LDA OPCODE ;
|
|
|
|
DIV PHA ;
|
|
|
|
AND #$07 ;
|
|
|
|
EOR #$07 ;
|
|
|
|
STA ZERO,X ;
|
|
|
|
PLA ;
|
|
|
|
LSR A ;
|
|
|
|
LSR A ;
|
|
|
|
LSR A ;
|
|
|
|
DEX ;
|
|
|
|
BNE DIV ;
|
|
|
|
STX FLAG ;
|
|
|
|
LSR A ;
|
|
|
|
BCS IMI ;
|
|
|
|
BEQ FIRST ;
|
|
|
|
IMARL LDA #$11 ; no, arilog
|
|
|
|
ADC ZERO+$01 ; SIMA
|
|
|
|
TAX ;
|
|
|
|
LDA #$00 ; set dest=A
|
|
|
|
STA ZERO+$01 ; SIMA
|
|
|
|
IMI BEQ MOVE ;
|
|
|
|
SECOND LDA #$07 ; offset for 2nd (page?)
|
|
|
|
FIRST ADC SPEED ;
|
|
|
|
TAX ; Transfer to Index
|
|
|
|
INX ;
|
|
|
|
|
|
|
|
|
|
|
|
MOVE TXA ; SET HIGH ADDRESS
|
|
|
|
ASL A ;
|
|
|
|
TAX ;
|
|
|
|
LDA XFERTBL,X ; GET LO ADOR
|
|
|
|
INX ;
|
|
|
|
PHA ; SET LO ADDRESS
|
|
|
|
LDA XFERTBL,X ;
|
|
|
|
PHA ;
|
|
|
|
LDX SPEED ; GET SOURCE INDEX
|
|
|
|
|
|
|
|
NOFETCH LDY SIMA,X ; GET SOURCE DATA IN Y ***
|
|
|
|
|
|
|
|
LDX ZERO+$01 ; GET DEST INDEX
|
|
|
|
LDA SIMA,X ;
|
|
|
|
STA ZERO ; SAVE DESTINATION DATA
|
|
|
|
LDA #$44 ; SET 6502 STATUS
|
|
|
|
PHA ;
|
|
|
|
TXA ; DEST IND, IN A & X
|
|
|
|
RTI ; GO INTERPRET
|
|
|
|
; RTS to stack pointer instruction
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
IN LSR A ;
|
|
|
|
BEQ XCHG ;
|
|
|
|
BCC INPUT ;
|
|
|
|
TAY ;
|
|
|
|
JSR CALL65 ;
|
|
|
|
STA SIMA ;
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; CALL 6502 SUBROUTINE
|
|
|
|
CALL65 LDA (PCL),Y ;
|
|
|
|
PHA ;
|
|
|
|
DEY ;
|
|
|
|
BPL CALL65 ;
|
|
|
|
JSR DBLINC ;
|
|
|
|
LDA #$00 ;
|
|
|
|
PHA ;
|
|
|
|
LDA SIMA ;
|
|
|
|
RTI ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
XCHG JSR RPSCR ;
|
|
|
|
LDX #$04
|
|
|
|
LDY #$02
|
|
|
|
JSR RPRP ;
|
|
|
|
LDX #$04
|
|
|
|
JMP SCRRP ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
XTHL JSR RPSCR ;
|
|
|
|
JSR SPPNT ;
|
|
|
|
LDX #$02
|
|
|
|
JSR MEMRP ;
|
|
|
|
LDX #$13
|
|
|
|
BNE RPMEM ;
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
IO LSR A ; which inst?
|
|
|
|
BNE LBL ;
|
|
|
|
STX INTE ; set/clear INTE
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
LBL LDX #$02 ; point to HL
|
|
|
|
BCC IN ; is it input
|
|
|
|
LSR A ; no, is it xthl?
|
|
|
|
BEQ XTHL ; yes
|
|
|
|
BCS JMPJUMPUN ; is it jump?
|
|
|
|
OUTPUT DEC FLAG ; no, flag an output
|
|
|
|
INPUT JSR IMM ; get port #
|
|
|
|
LDA SRC ; SRC = port number
|
|
|
|
AND #$0F ; clear high bits (FF => 0F) because why keep up with 256 ports when we only need 16?
|
|
|
|
ASL A ; double index for hi/lo byte in table
|
|
|
|
TAX ; port table offset in X
|
|
|
|
LDY #$02 ;
|
|
|
|
IOPLP LDA IOTBLOUT,X ; get IO address
|
|
|
|
STA FLAG,Y ; store in pointer
|
|
|
|
INX ; bump index
|
|
|
|
DEY ; decrement counter
|
|
|
|
BNE IOPLP ;
|
|
|
|
INY ; point to data dir, reg
|
|
|
|
PNTPRT DEY ; point to port
|
|
|
|
LSR FLAG ; FLAG is FF on OUTPUT, 00 on INPUT
|
|
|
|
BCC IOIN ; do input if carry clear.
|
|
|
|
LDA SIMA ; - if carry set, OUTPUT
|
|
|
|
IOOUT
|
|
|
|
STA (DESTDA),Y ; OUTPUT TO PORT
|
|
|
|
JSR SIOOUT ; TELL SIO I HAVE PUT A BYTE TO SEND
|
|
|
|
BCS IOEX ; should return with Carry set???
|
|
|
|
|
|
|
|
IOIN
|
|
|
|
INC DESTDA ; switch from PORT-OUT to PORT-IN
|
|
|
|
TYA
|
|
|
|
PHA
|
|
|
|
JSR SIOIN ; TELL SIO I WANT A BYTE - Y=PORT
|
|
|
|
PLA
|
|
|
|
TAY
|
|
|
|
LDA (DESTDA),Y ; input from port
|
|
|
|
STA SIMA ; store in SIMA
|
|
|
|
|
|
|
|
IOEX RTS ;
|
|
|
|
|
|
|
|
JMPJUMPUN JMP JUMPUN ; spaghetti
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
ARIM JSR IMM ;
|
|
|
|
CLC ;
|
|
|
|
JMP IMARL ;
|
|
|
|
|
|
|
|
JMPCALLUN JMP CALLUN ; spaghetti
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
PUSH LSR A ; IS THIS A PUSH?
|
|
|
|
BCS SKP ; YES, GO PUSH
|
|
|
|
CMP #$03 ; NO, IS THIS A CALL?
|
|
|
|
BEQ JMPCALLUN ; YES, GO CALL
|
|
|
|
JMP UNDEF ; NO, UNDEFINED
|
|
|
|
|
|
|
|
SKP ASL A ;MAKE AN INDEX
|
|
|
|
TAX ;IS IT PUSH PSW?
|
|
|
|
BNE PUSHT ; NO, KEEP INDEX
|
|
|
|
DEX ;YES, ADJUST INDEX
|
|
|
|
|
|
|
|
PUSHT TXA ; TEMP SAVE - x=0A on set return, gets PCL/H
|
|
|
|
PHA ;
|
|
|
|
JSR DECSP ; DECREMENT STACK POINTER
|
|
|
|
JSR SPPNT ; IT BECOMES POINTER
|
|
|
|
PLA ; RECOVER TEMP SAVE
|
|
|
|
TAX ;
|
|
|
|
|
2019-10-11 01:27:34 +00:00
|
|
|
|
2019-07-17 13:52:26 +00:00
|
|
|
|
|
|
|
RPMEM LDY #$01 ; CLEAR INDEX
|
|
|
|
|
|
|
|
; compare to 8f, THEN add 10 if necessary
|
|
|
|
|
|
|
|
;CLC
|
|
|
|
LDA DESTDA,Y ; $04 + $12 = $16 DESTDA
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
CMP #$7F ; over 9000?
|
2019-10-11 01:27:34 +00:00
|
|
|
BCC RPMEM2 ; nope, skip math
|
|
|
|
|
|
|
|
SBC #$80 ; off by $10 ??? ***
|
2019-07-17 13:52:26 +00:00
|
|
|
STA RAMWRTON ; write to AUX
|
|
|
|
STA DESTDA,Y
|
|
|
|
|
|
|
|
RPMEM2 CPX #$02 ; ****
|
|
|
|
BNE RPLP ; **** add $10 to SRC+1 ON SHLD, X=2
|
|
|
|
; E5 PUSH H AXY=02/02/01
|
|
|
|
; 22 SHLD AXY=02/01/01
|
|
|
|
LDA OPCODE ; is it PUSH H or SHLD? <-- corner case!
|
|
|
|
CMP #$22
|
|
|
|
BNE STADESTDA
|
|
|
|
LDA DESTDA,Y
|
|
|
|
CLC ; ADD 10 to destination on SHLD
|
|
|
|
ADC #$10
|
|
|
|
STA DESTDA,Y ; ****
|
|
|
|
|
|
|
|
STADESTDA LDA RAMWRT ; if writing to aux, add 80 back and write to main
|
|
|
|
BPL RPLP
|
|
|
|
CLC
|
|
|
|
LDA DESTDA,Y
|
|
|
|
ADC #$80
|
|
|
|
STA DESTDA,Y
|
|
|
|
STA RAMWRTOFF ; write to MAIN
|
|
|
|
|
|
|
|
RPLP LDA SIMM,X ;GET NEXT RP DATA
|
|
|
|
PHA ; hang onto it
|
|
|
|
LDA DESTDA+1
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
|
|
|
|
CMP #$8F ; over 9000 or under 1000?
|
|
|
|
BCS STADESTDA3 ; over 9000
|
|
|
|
CMP #$10
|
|
|
|
BCS STADESTDA2 ; Over 1000, skip
|
|
|
|
|
|
|
|
STADESTDA3 SEC
|
2019-10-11 01:27:34 +00:00
|
|
|
|
|
|
|
SBC #$80
|
2019-07-17 13:52:26 +00:00
|
|
|
STA RAMWRTON
|
|
|
|
STA DESTDA+1
|
|
|
|
|
|
|
|
STADESTDA2 PLA ; get RP data back
|
|
|
|
STA (DESTDA),Y ;STORE IN MEMORY
|
|
|
|
|
|
|
|
LDA RAMWRT ; if writing to aux, add 80 back and write to main
|
|
|
|
BPL RPLP2
|
|
|
|
CLC
|
|
|
|
LDA DESTDA+1
|
2019-10-11 01:27:34 +00:00
|
|
|
|
|
|
|
ADC #$80
|
2019-07-17 13:52:26 +00:00
|
|
|
STA DESTDA+1
|
|
|
|
STA RAMWRTOFF ; write to MAIN
|
|
|
|
|
|
|
|
RPLP2 DEX ;
|
|
|
|
DEY ;
|
|
|
|
BEQ RPLP ;
|
|
|
|
|
|
|
|
CPX #$00 ; ****
|
|
|
|
BNE RTS ; **** reset SRC+1 ON SHLD, X=2
|
|
|
|
INY
|
|
|
|
INY
|
|
|
|
SEC
|
|
|
|
LDA DESTDA,Y ; $04 + $12 = $16 DESTDA
|
|
|
|
SBC #$10
|
|
|
|
PHA ; hold that thought...
|
|
|
|
LDA RAMWRT ; writing to AUX? turn that off.
|
|
|
|
BPL RPLP3
|
|
|
|
CLC
|
|
|
|
LDA DESTDA,Y
|
|
|
|
ADC #$80
|
|
|
|
RPLP3 STA RAMWRTOFF
|
|
|
|
PLA ; and we're back.
|
|
|
|
STA DESTDA,Y ; ****
|
|
|
|
|
|
|
|
|
|
|
|
RTS RTS ;
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
JMP CLV ; INDICATE A JUMP
|
|
|
|
|
|
|
|
CALL JSR CONDIT ; TEST CONDITION
|
|
|
|
BEQ CALLUN ; MET
|
|
|
|
JMP DBLINC ; NOT MET, increment PC
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
JUMPUN CLV ; INDICATE A JUMP
|
|
|
|
CALLUN PHP ; preserve overflow, etc
|
|
|
|
|
|
|
|
CALLUN3 JSR PCPNT ; GET NEXT 2 BYTES
|
|
|
|
|
|
|
|
|
|
|
|
CALLUN4 LDX #$13 ; INTO SCRATCH
|
|
|
|
JSR MEMRP ;
|
|
|
|
|
|
|
|
; **** add $10 to SRC+1
|
|
|
|
CLC
|
|
|
|
LDA SRC+1
|
|
|
|
PHA
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
CMP #$7F ; is above 32k?
|
|
|
|
BCC CALLUN5
|
|
|
|
LDA #$01
|
|
|
|
STA HIPCH ; if destination PCH is above 32k?
|
|
|
|
CALLUN5 PLA
|
|
|
|
CLC
|
|
|
|
ADC #$10 ; CLEARS OVERFLOW?
|
|
|
|
STA SRC+1
|
|
|
|
;****
|
|
|
|
|
|
|
|
PLP ; get overflow, etc.
|
|
|
|
|
|
|
|
CALLUN2 BVC JM ; JUMP on overflow clear
|
|
|
|
JSR DBLINC ; otherwise? BUMP PC twice
|
|
|
|
|
|
|
|
SVR LDX #$0A ; SAVE RETURN for RST
|
|
|
|
|
|
|
|
LDA HIPCH ; return address should be HIPCH as well
|
|
|
|
BEQ SVR1
|
|
|
|
LDA PCH
|
|
|
|
CLC
|
|
|
|
ADC #$80
|
|
|
|
STA PCH
|
|
|
|
|
|
|
|
; **** subtract 10 before setting return point
|
|
|
|
SVR1 SEC
|
|
|
|
LDA PCH
|
|
|
|
SBC #$10
|
|
|
|
STA PCH
|
|
|
|
;****
|
|
|
|
|
|
|
|
JSR PUSHT ; ON STACK **** <--- and if SP is >9000?
|
|
|
|
|
|
|
|
; **** add 10 after setting return point ???
|
|
|
|
CLC
|
|
|
|
LDA PCH
|
|
|
|
ADC #$10
|
|
|
|
STA PCH
|
|
|
|
;****
|
|
|
|
|
|
|
|
JM LDX #$0A ; POINT TO PC
|
|
|
|
|
|
|
|
; **** doing a JUMP or CALL - reset HIPCH
|
|
|
|
LDA #$00
|
|
|
|
STA HIPCH
|
|
|
|
; **** doing a JUMP or CALL - reset HIPCH
|
|
|
|
|
|
|
|
JMP SCRRP ; GIVE IT NEW ADDRESS
|
|
|
|
|
|
|
|
JMPSVR JMP SVR ; SPAGHETTI!
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
RETURN JSR CONDIT ; TEST CONDITION
|
|
|
|
BNE RTS ; NOT MET
|
|
|
|
RETUN
|
|
|
|
; if SPH > 8F or < 10, subtract 80, read from AUX, write to AUX !!!
|
|
|
|
; **** doing a JUMP or CALL - reset HIPCH
|
|
|
|
LDA #$00
|
|
|
|
STA HIPCH
|
2019-10-11 01:27:34 +00:00
|
|
|
|
2019-07-17 13:52:26 +00:00
|
|
|
; **** doing a JUMP or CALL - reset HIPCH
|
|
|
|
|
|
|
|
LDA SPH
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
|
|
|
|
CMP #$8F
|
|
|
|
BCS RETUN1
|
|
|
|
CMP #$10
|
|
|
|
BCS RETUN2
|
|
|
|
SEC
|
2019-10-11 01:27:34 +00:00
|
|
|
RETUN1
|
|
|
|
SBC #$80 ; *** SPH off by $10?
|
2019-07-17 13:52:26 +00:00
|
|
|
STA RAMRDON
|
|
|
|
STA RAMWRTON
|
|
|
|
STA SPH
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; **** add $10 to (SP) before grabbing return point
|
|
|
|
RETUN2 CLC
|
|
|
|
LDY #$01
|
|
|
|
LDA (SPL),Y ; get byte at (SPL/H)
|
|
|
|
ADC #$10
|
|
|
|
STA (SPL),Y
|
|
|
|
;****
|
|
|
|
|
|
|
|
LDA RAMRD ; if reading/writing AUX, switch back to MAIN
|
|
|
|
BPL RETUN3
|
|
|
|
LDA SPH ; return SPH to high value
|
|
|
|
CLC
|
2019-10-11 01:27:34 +00:00
|
|
|
ADC #$80 ; *** SPH off by $10?
|
2019-07-17 13:52:26 +00:00
|
|
|
STA SPH
|
|
|
|
STA RAMRDOFF
|
|
|
|
STA RAMWRTOFF
|
|
|
|
|
|
|
|
RETUN3 LDX #$0A ; POP RETURN OFF
|
|
|
|
BNE POPIT ; STACK INTO PC
|
|
|
|
|
|
|
|
RST LDA OPCODE ; CONVERT INSTRUCTION
|
|
|
|
AND #$38 ; TO RESET VECTOR
|
|
|
|
STA SRC ; STORE IT IN SCRATCH
|
|
|
|
LDA #$00
|
|
|
|
STA HIPCH ; no longer need to inc the PCH if we're resetting to 0038
|
|
|
|
LDA #$10 ; HIGH RESET VECTOR
|
|
|
|
STA SRC+1 ; ??? SCR+1 ???
|
|
|
|
BCC JMPSVR ;
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
POP LSR A ; POP?
|
|
|
|
BCC OTH ; NO
|
|
|
|
ASL A ;
|
|
|
|
TAX ; POP PSW?
|
|
|
|
BNE POPIT ; NO, KEEP INDEX
|
|
|
|
DEX ; YES, ADJUST INDEX
|
|
|
|
|
|
|
|
POPIT TXA ; TEMP SAVE INDEX
|
|
|
|
PHA ;
|
|
|
|
|
|
|
|
|
|
|
|
JSR SPPNT ; PULL OUT STACK DATA
|
|
|
|
PLA ; BUMP SP
|
|
|
|
TAX ;
|
|
|
|
JSR MEMRP ; SP IS POINTER
|
|
|
|
ICISP JSR ISP ; RECOVER TEMP
|
|
|
|
ISP LDX #$08 ;
|
|
|
|
JMP INC ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
OTH LDX #$02 ; POINT TO HL
|
|
|
|
LDY #$08 ; ASSUME SPHL
|
|
|
|
ASL A ; IS IT SPHL?
|
|
|
|
BEQ SPHL ; YES, GO DO IT
|
|
|
|
CMP #$04 ; NO, WHAT IS IT?
|
|
|
|
BEQ UNDEF ; UNDEFINED
|
|
|
|
BPL RETUN ; RETURN
|
|
|
|
LDY #$0A ; PCHL
|
|
|
|
|
|
|
|
; **** ; if it's a PCHL, add $10 to SIMH to offset subtracting after the operation.
|
|
|
|
|
|
|
|
LDA SIMH ; ****
|
|
|
|
CLC ; ****
|
|
|
|
ADC #$10 ; ****
|
|
|
|
STA SIMH ; ****
|
|
|
|
|
|
|
|
SPHL JMP RPRP ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
CONDIT
|
|
|
|
LSR A ; MAKE INDEX TO MASK. TABLE
|
|
|
|
TAX ;
|
|
|
|
LDA MSKTBL,X ; GET CONDITION FLAG MASK
|
|
|
|
AND PSW ; IS CONDITION SET*
|
|
|
|
BCS RTN ; LEAVE Z FLAG SET
|
|
|
|
EOR MSKTBL,X ; OR REVERSE IT
|
|
|
|
RTN RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
NOP LDA OPCODE ; CHECK INSTRUCTION
|
|
|
|
BEQ RTN ; Pointer says 00 == NOP
|
|
|
|
UNDEF ;LDY #$0C ; ILLEGAL OPCODE, UNDEFINED
|
|
|
|
;LDX #$0A ;
|
|
|
|
;JSR INCDEC ;
|
|
|
|
;JMP MNSTRT ; ignore and move on.
|
|
|
|
;JSR BELL ; Beep, then RTS
|
|
|
|
RTS ; RTS on illegal/undefined opcode ?
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
DADLXI LSR A ; DROP LSB
|
|
|
|
ASL A ;
|
|
|
|
BNE NSP ; USE SP?
|
|
|
|
LDA #$08 ; YES, POINT TO IT
|
|
|
|
|
|
|
|
|
|
|
|
NSP PHA ; SAVE POINTER a=8
|
|
|
|
TXA ; GET DESTINATION INDEX
|
|
|
|
LSR A ; DAD?
|
|
|
|
BCS LXI ; NO, GO DO LXI
|
|
|
|
DAD PLA ; YES, RECOVER POINTER a=8
|
|
|
|
TAY ;
|
|
|
|
LDX #$02 ; SET HL AS DESTINATION
|
|
|
|
|
|
|
|
LDA OPCODE ; **** subtract 10 from SPH before working with it / DAD SP
|
|
|
|
CMP #$39 ; if we're working with stack pointer
|
|
|
|
BNE DAD2
|
|
|
|
LDA SPH
|
|
|
|
SEC
|
|
|
|
SBC #$10
|
|
|
|
STA SPH ; **** subtract 10 from SPH before working with it
|
|
|
|
|
|
|
|
DAD2 JSR INCDEC ; GO ADD RP & HL
|
|
|
|
|
|
|
|
PHA ; **** if we're working with DAD SP
|
|
|
|
PHP ; preserve carry set, etc
|
|
|
|
LDA OPCODE
|
|
|
|
CMP #$39
|
|
|
|
BNE CARRY2
|
|
|
|
LDA SPH ; **** add 10 to SPH after working with it
|
|
|
|
CLC
|
|
|
|
ADC #$10
|
|
|
|
STA SPH
|
|
|
|
CARRY2 PLP ; reset carry, etc
|
|
|
|
PLA ; **** add 10 to SPH after working with it
|
|
|
|
|
|
|
|
CARRY TAY ; SAVE RESULT
|
|
|
|
ROL A ; BRING IN CARRY
|
|
|
|
EOR FLAG ; CHG TO BORROW IF SUBTRACT
|
|
|
|
LSR PSW ;
|
|
|
|
LSR A ; RESTORE CARRY(BORROW)
|
|
|
|
ROL PSW ;
|
|
|
|
TYA ; RECOVER RESULT
|
|
|
|
|
|
|
|
|
|
|
|
RTS
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
LXI JSR PCPNT ; PC INTO PNT
|
|
|
|
PLA ; RECOVER POINTER
|
|
|
|
TAX ; USE TO INDEX DESTINATION RP
|
|
|
|
JSR MEMRP ; MOVE IMMEDIATE DATA TO RP
|
|
|
|
; if RP is SP, add 10 to SPH
|
|
|
|
; ****
|
|
|
|
LDA OPCODE
|
|
|
|
CMP #$31
|
|
|
|
BNE LXI2
|
|
|
|
CLC
|
|
|
|
LDA SPH
|
|
|
|
ADC #$10
|
|
|
|
STA SPH
|
|
|
|
; ****
|
|
|
|
LXI2 JMP DBLINC ; BUMP PROGRAM COUNTER
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
LDSTR BIT FOUR ; INDIRECT?
|
|
|
|
BEQ DIRECT ; NO
|
|
|
|
LSR A ; STAX?
|
|
|
|
BCC LDAX ; NO
|
|
|
|
STAX
|
|
|
|
INX ; **** add 10 to DESTDA
|
|
|
|
CLC
|
|
|
|
LDA PSW,X
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
CMP #$7F ; over 9000?
|
|
|
|
BCC STAX1 ; nope, carry on
|
|
|
|
SBC #$80 ; yep, subtract 80
|
|
|
|
STA RAMWRTON ; write AUX
|
|
|
|
CLC
|
|
|
|
STAX1 ADC #$10
|
|
|
|
|
|
|
|
|
|
|
|
STAX2 STA PSW,X ; store updated destination address
|
|
|
|
DEX ; ****
|
|
|
|
LDA SIMA ; YES,STORE A
|
|
|
|
STA (PSW,X) ; PSW = 04 + 12 = 16 = destDA
|
|
|
|
INX ; **** reset DESTDA
|
|
|
|
SEC
|
|
|
|
LDA PSW,X
|
|
|
|
SBC #$10
|
|
|
|
LDY RAMWRT ; load Y? Y not!?
|
|
|
|
BPL STAX3
|
|
|
|
CLC
|
|
|
|
ADC #$80
|
|
|
|
STA RAMWRTOFF ; back to MAIN
|
|
|
|
STAX3 STA PSW,X
|
|
|
|
DEX ; ****
|
|
|
|
|
|
|
|
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
DIRECT PHA ; TEMP SAVE
|
|
|
|
JSR PCPNT ; PC TO POINTER
|
|
|
|
JSR DBLINC ;
|
|
|
|
LDX #$13 ;
|
|
|
|
JSR MEMRP ;
|
|
|
|
|
|
|
|
; **** if LHLD, add 10 to SRC before grabbing memory contents
|
|
|
|
LDA OPCODE
|
|
|
|
CMP #$2A
|
|
|
|
BNE DIRECT2
|
|
|
|
LDA SRC+1
|
|
|
|
CLC
|
|
|
|
ADC #$10
|
|
|
|
STA SRC+1
|
|
|
|
; **** if LHLD, add 10 to SRC before grabbing memory contents
|
|
|
|
|
|
|
|
DIRECT2 LDX #$11 ;
|
|
|
|
JSR SCRRP ;
|
|
|
|
PLA ; RECOVER TEMP
|
|
|
|
LSR A ; LOAD?
|
|
|
|
BCS STORE ; NO, STORE
|
|
|
|
ASL A ;
|
|
|
|
TAX ;
|
|
|
|
BEQ LDAD ;
|
|
|
|
JMP MEMRP ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
LDAD LDX #$11 ;
|
|
|
|
|
|
|
|
LDAX CLC ; ****
|
|
|
|
INX
|
|
|
|
LDA SIMA,X
|
|
|
|
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
|
|
|
|
CMP #$7F ; over 9000?
|
|
|
|
BCC LDAX1
|
|
|
|
SBC #$80
|
|
|
|
STA RAMRDON
|
|
|
|
|
|
|
|
CLC
|
|
|
|
LDAX1 ADC #$10
|
|
|
|
STA SIMA,X
|
|
|
|
|
|
|
|
|
|
|
|
LDAX2 DEX ; ****
|
|
|
|
|
|
|
|
LDA (SIMA,X) ;
|
|
|
|
STA SIMA ;
|
|
|
|
|
|
|
|
SEC ; ****
|
|
|
|
INX
|
|
|
|
LDA SIMA,X
|
|
|
|
SBC #$10
|
|
|
|
STA SIMA,X
|
|
|
|
|
|
|
|
LDA RAMRD
|
|
|
|
BPL LDAX3
|
|
|
|
STA RAMRDOFF ; back to MAIN
|
|
|
|
LDA SIMA,X
|
|
|
|
CLC
|
|
|
|
ADC #$80
|
|
|
|
STA SIMA,X
|
|
|
|
|
|
|
|
LDAX3 DEX ; ****
|
|
|
|
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
STORE ASL A ; MAKE INDEX
|
|
|
|
TAX ;
|
|
|
|
BEQ STAD ; STORE A DIRECT?
|
|
|
|
|
|
|
|
JMP RPMEM ; NO, STORE HL DIRECT SHLD
|
|
|
|
|
|
|
|
STAD LDX #$12 ; POINT TO POINTER
|
|
|
|
JMP STAX ; jump to STAX
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
INXDCX LDY #$0C ; SET FOR DECREMENT
|
|
|
|
LSR A ;
|
|
|
|
BCC DRP ; YES
|
|
|
|
LDY #$0E ; NO, SET FOR INCR
|
|
|
|
DRP ASL A ; DROP LSB
|
|
|
|
BNE NOR ; FOR SP?
|
|
|
|
LDA #$08 ; YES, POINT TO SP
|
|
|
|
NOR TAX ; USE AS INDEX
|
|
|
|
JMP INCDEC ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
DCR SEC ; SET FOR DECREMENT
|
|
|
|
DEC FLAG ;
|
|
|
|
INR LDY #$01 ; SET FOR INCREMENT
|
|
|
|
BTH JSR ADDR ; GO ADD
|
|
|
|
JMP STATUS2 ; SET STATUS, NOT CARRY
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
MVI JSR IMM ; GET IMMEDIATE BYTE
|
|
|
|
JMP MOVE ; MOVE IT TO DESTINATION
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
MOVIT TYA ; GET SOURCE DATA
|
|
|
|
MVIT1 DEX ; IS DEST MEMORY?
|
|
|
|
BNE NMEM ; NO
|
|
|
|
|
|
|
|
INX ; ****
|
|
|
|
PHA ; ****
|
|
|
|
LDA SIML,X ; **** SIMH
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
CMP #$7F ; above 8000?
|
|
|
|
; above 9000 after adding $10 !!!
|
|
|
|
BCC MVIT2
|
|
|
|
STA RAMWRTON ; set AUX WRITE
|
|
|
|
SBC #$80 ; SBC #$80
|
|
|
|
CLC ; ****
|
|
|
|
|
|
|
|
MVIT2 ADC #$10 ; add #$10
|
|
|
|
|
|
|
|
; store in AUX
|
|
|
|
; add #$80
|
|
|
|
; set MAIN WRITE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STASIMH STA SIML,X ; ****
|
|
|
|
PLA ; ****
|
|
|
|
DEX ; ****
|
|
|
|
|
|
|
|
STA (SIML,X) ; YES STORE IN MEMORY
|
|
|
|
INX ; ****
|
|
|
|
PHA ; **** byte into stack
|
|
|
|
|
|
|
|
LDA RAMWRT
|
|
|
|
BPL STASIMH2
|
|
|
|
LDA SIML,X
|
|
|
|
STA RAMWRTOFF ; AUX OFF, write to MAIN
|
|
|
|
CLC
|
|
|
|
ADC #$80
|
|
|
|
STA SIML,X
|
|
|
|
|
|
|
|
STASIMH2 SEC ; ****
|
|
|
|
LDA SIML,X ; ****
|
|
|
|
SBC #$10 ; **** subtract 10
|
|
|
|
STA SIML,X ; ****
|
|
|
|
|
|
|
|
NOMOV PLA ; ****
|
|
|
|
DEX ; ****
|
|
|
|
|
|
|
|
NMEM STA SIMM,X ; STORE IN DEST REGISTER
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
ADC CLV ; FLAG W/CARRY
|
|
|
|
BVC ADD ;
|
|
|
|
|
|
|
|
CMP LDX #$13 ; CHG DEST TO SCR
|
|
|
|
BNE SUB ; SO ONLY PSW IS AFFECTED
|
|
|
|
|
|
|
|
SBB CLV ; FLAG W/BORROW
|
|
|
|
SUB DEC FLAG ; F L A G = FF FOR SUBTRACT
|
|
|
|
SEC ;
|
|
|
|
|
|
|
|
ADD JMP ADCRY ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
ORA TYA ; GET SOURCE DATA
|
|
|
|
ORA SIMA ; LOGICAL OR
|
|
|
|
BCC SOM ; SET FOR A CLEAR AUX CRY
|
|
|
|
|
|
|
|
XRA TYA ; G E T SOURCE DA T A
|
|
|
|
EOR SIMA ; LOGICAL EXCLUSIVE OR
|
|
|
|
SOM LDY #$00 ; 00 WON'T SET ANY FLAGS
|
|
|
|
BEQ ALL ; GO SAVE RESULT
|
|
|
|
|
|
|
|
ANA TYA ; G E T SOURCE DA T A
|
|
|
|
PHA ; SAVE IT
|
|
|
|
ORA SIMA ; LOGICAL OR OF BIT
|
|
|
|
ASL A ; T H R E E BECOMES AUX CARRY
|
|
|
|
AND #$10 ;
|
|
|
|
TAY ;
|
|
|
|
PLA ; GET SOURCE DATA
|
|
|
|
AND SIMA ; LOGICAL AND
|
|
|
|
|
|
|
|
ALL STY SRC+1 ; SAVE FLAG SETTING DATA
|
|
|
|
STA SIMA ; LOGICAL RESULT INTO A
|
|
|
|
JSR STATUS2 ; SET STATUS
|
|
|
|
LDA #$EE ; SELECT STATUS BITS TO CLEAR
|
|
|
|
CYAC AND PSW ; CLEAR SELECTED BITS
|
|
|
|
ORA SRC+1 ; SET SELECTED BITS
|
|
|
|
STPSW STA PSW ; SAVE NEW PSW
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
2019-10-11 01:27:34 +00:00
|
|
|
ROTATE LDY SIMA ; GET ACCUMULATOR
|
|
|
|
LSR A ; IS THIS CMC OR 8TC?
|
|
|
|
BNE ROCOMP ; NO, IT IS A ROTATE .OR CMA
|
|
|
|
LDA PSW ; YES, CHANGE CARRY
|
|
|
|
EOR #$01 ; CMC
|
2019-07-17 13:52:26 +00:00
|
|
|
BCC STPS ;
|
2019-10-11 01:27:34 +00:00
|
|
|
ORA #$01 ; STC
|
2019-07-17 13:52:26 +00:00
|
|
|
STPS BVS STPSW ;
|
2019-10-11 01:27:34 +00:00
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ROCOMP BCS LEFT ; LEFT OR RIGHT?
|
|
|
|
LSR A ; CMA?
|
|
|
|
BNE ROT ; NO, ROTATE
|
|
|
|
TYA ; YES, COMMPLEMFNT A
|
|
|
|
EOR #$FF ;
|
|
|
|
STA SIMA ; DOESN* T SET STATUS
|
2019-07-17 13:52:26 +00:00
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
2019-10-11 01:27:34 +00:00
|
|
|
ROT TYA ; GET ACCUMULATOR
|
2019-07-17 13:52:26 +00:00
|
|
|
BCS RRC ;
|
2019-10-11 01:27:34 +00:00
|
|
|
LDA PSW ; GET 8080 CARRY
|
2019-07-17 13:52:26 +00:00
|
|
|
RRC LSR A ;
|
2019-10-11 01:27:34 +00:00
|
|
|
TYA ; GET ACCUMULATOR
|
|
|
|
ROR A ; ROTATE RIGHT
|
|
|
|
BVS JCRY ; GO STORE&SET CARRY
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
LEFT LSR A ; DECIMAL ADJUST? IYES# GO 00 IT
|
|
|
|
BEQ DAA ; N 0 , GET ACCUMULATOR
|
|
|
|
TYA ; JRLC?
|
|
|
|
BCS RLC ; NO#GET 8080 CARRY
|
|
|
|
LDA PSW ; MOVE IT INTO MSNIB
|
|
|
|
ROR A ;
|
|
|
|
ROR A ;
|
|
|
|
RLC ASL A ; MOVE IT INTO CARRY
|
|
|
|
TYA ; G E T ACCUMULATOR
|
|
|
|
ROL A ; MOVE IT LEFT
|
|
|
|
JCRY STA SIMA ; SAVE IT
|
|
|
|
JMP CARRY ; GO SET STATUS
|
|
|
|
|
2019-07-17 13:52:26 +00:00
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
DAA CLC ;
|
2019-10-11 01:27:34 +00:00
|
|
|
PHP ;PRE3ERVE STATUS |
|
|
|
|
TYA ;GET SOURCE DATA
|
|
|
|
STA ZERO ; PREP FOR ADD
|
|
|
|
AND #$0F ;LOOK AT LSNI8
|
|
|
|
ADC #$06 ;IF *0A WILL CAUSE AUX CRY
|
|
|
|
ORA PSW ;OR I F AC I S ALREADY SET
|
|
|
|
AND #$10 ; EITHER SET?
|
|
|
|
BEQ NOSIX ;NO, DON T ADJUST LSNIB
|
|
|
|
LDA #$06 ; YES# ADJUST IT
|
|
|
|
NOSIX TAY ;
|
|
|
|
ADC ZERO ; G E T SOURCE
|
2019-07-17 13:52:26 +00:00
|
|
|
BCS SXTY ;
|
2019-10-11 01:27:34 +00:00
|
|
|
ADC #$60 ;113 MSNIB NOW > A0T IIF SO* CARRY IS SET
|
|
|
|
ROL A ;G E T CARRY
|
|
|
|
ORA PSW ;OR WITH 8080 CARRY
|
|
|
|
LSR A ;I S EITHER SETT
|
|
|
|
BCC DA ;NO# DON'T ADJUST MSNIB l
|
|
|
|
SXTY TYA ;YES* ADJUST MSN!B I
|
|
|
|
ADC #$5F ;(5F + CARRY = 60)
|
2019-07-17 13:52:26 +00:00
|
|
|
TAY ;
|
2019-10-11 01:27:34 +00:00
|
|
|
DA LDX #$00 ;DESTINATION IS A
|
|
|
|
PLP ;RESTQRE STATUS
|
2019-07-17 13:52:26 +00:00
|
|
|
ADCRY JSR ADDR ;
|
|
|
|
JSR CARRY ;
|
2019-10-11 01:27:34 +00:00
|
|
|
|
|
|
|
|
2019-07-17 13:52:26 +00:00
|
|
|
STATUS2
|
2019-10-11 01:27:34 +00:00
|
|
|
TAY ; SAVE RESULT
|
|
|
|
ROL PSW ; CLEAR P3W SIGN BIT
|
|
|
|
ASL A ; PUT NEW SIGN IN CARRY
|
|
|
|
STA FLAG ; C L E A R L S B OF F L A G
|
|
|
|
LDA PSW ; PUT NEW SIGN IN P3N
|
|
|
|
ROR A ;
|
|
|
|
SGN ORA #$46 ; PRESET Z*P 8 PRESET
|
|
|
|
TAX ; 3AVE IN X
|
|
|
|
TYA ; RECOVER WORD
|
|
|
|
BEQ DONE ; I F ZERO*ALL DONE
|
|
|
|
FLIP INC FLAG ; IFLIP FLAG |
|
|
|
|
PAR LSR A ; TEST EACH BIT I
|
|
|
|
BEQ ALL2 ; NO MORE BITS
|
2019-07-17 13:52:26 +00:00
|
|
|
BCC PAR ;
|
|
|
|
ALL2 BCS FLIP ;
|
2019-10-11 01:27:34 +00:00
|
|
|
LSR FLAG ; TEST FLAG
|
|
|
|
TXA ; RECOVER P3w
|
|
|
|
AND #$BF ; CLEAR Z
|
|
|
|
BCS REC ; PARITY EVENT
|
|
|
|
AND #$FB ; N0* CLEAR P
|
|
|
|
REC TAX ; BACK TO X
|
|
|
|
DONE STX PSW ; STORE AS PSW
|
|
|
|
RTS ;
|
2019-07-17 13:52:26 +00:00
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
PCPNT LDX #$0A ; **** 0A + 05/06 = 0F = PCL/PCH
|
|
|
|
RPPNT LDY #$11 ; 05 + 11 = 16 = store at DESTDA
|
|
|
|
BNE RPRP ; never zero, branch always
|
|
|
|
RPSCR LDY #$13 ; store at SRC instead
|
|
|
|
|
|
|
|
; moves scratchpad or other RP bytes to PC, vice versa
|
|
|
|
RPRP
|
|
|
|
|
|
|
|
LDA SIMA,X ; load SOURCE BYTE L
|
|
|
|
STA SIMA,Y ; store at DESTINATION L
|
|
|
|
LDA SIMM,X ; load SOURCE BYTE H
|
|
|
|
|
|
|
|
CPY #$08 ; **** if SPHL
|
|
|
|
BNE RPRP4 ; ****
|
|
|
|
CLC ; ****
|
|
|
|
ADC #$10 ; ****
|
|
|
|
JMP RPRP2
|
|
|
|
|
|
|
|
RPRP4 CPX #$0A ; X=0A, PC IS POINTER.
|
|
|
|
BNE RPRP2
|
|
|
|
LDA HIPCH ; HIPCH = 1, inc resulting pointer by 70
|
|
|
|
BEQ RPRP3
|
|
|
|
CLC
|
|
|
|
LDA SIMM,X
|
|
|
|
ADC #$80 ; 70 or 80? oof...
|
|
|
|
JMP RPRP2
|
|
|
|
|
|
|
|
RPRP3 LDA SIMM,X
|
|
|
|
|
|
|
|
RPRP2 STA SIMM,Y ; store at DESTINATION H
|
|
|
|
|
|
|
|
RPRTS RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
SCRRP TXA ; RP is destination (RP is a Register Pair)
|
|
|
|
TAY ; 0A on CALL (for return address???)
|
|
|
|
LDX #$13 ; SCR is source
|
|
|
|
BNE RPRP ; never zero, branch always
|
|
|
|
|
|
|
|
SPPNT LDX #$08 ; SP is Source
|
|
|
|
BNE RPPNT ; jump RPPNT
|
|
|
|
|
|
|
|
DBLINC JSR INCPC ; Increments PC twice
|
|
|
|
; ADVANCE COUNTER
|
|
|
|
|
|
|
|
INCPC LDX #$0A ; INC PC - $0A + $05 = $0F = PCL
|
|
|
|
INC LDY #$0E ; point to INC data - $0E + $05 = $13 = INCIT (0001)
|
|
|
|
INCDEC CLC ;
|
|
|
|
|
|
|
|
INDE LDA SIMA,X ; get register/PC value
|
|
|
|
ADC SIMA,Y ; add value from
|
|
|
|
STA SIMA,X ; save
|
|
|
|
INY ; bump indexes
|
|
|
|
INX ;
|
|
|
|
TYA ; check index 0E->0F
|
|
|
|
AND #$01 ; last pass? - increment HI byte
|
|
|
|
BNE INDE ; not done, loop
|
|
|
|
|
|
|
|
RTS ; yes
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
DECSP JSR DSP ; DEC SP twice
|
|
|
|
DSP LDX #$08 ; DEC SP
|
|
|
|
DEC LDY #$0C ; point to DEC data
|
|
|
|
BNE INCDEC ; go do it
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
MEMRP TYA ; grab source pointer offset
|
|
|
|
|
|
|
|
|
|
|
|
LDA DESTDA+1
|
|
|
|
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
|
|
|
|
CMP #$8F ; *** off by $10 *** WTF ***
|
|
|
|
BCS AUXMEMRP
|
|
|
|
CMP #$10 ; less than $10, rolled over from $F0
|
|
|
|
BCS MRLP1
|
|
|
|
AUXMEMRP STA RAMRDON ; read from AUX
|
|
|
|
SEC
|
2019-10-11 01:27:34 +00:00
|
|
|
SBC #$80
|
2019-07-17 13:52:26 +00:00
|
|
|
STA DESTDA+1
|
|
|
|
|
|
|
|
MRLP1 LDY #$01 ; move data in memory
|
|
|
|
|
|
|
|
MRLP LDA (DESTDA),Y ; get next byte
|
|
|
|
STA SIMM,X ; store in destination
|
|
|
|
DEX ; bump indices
|
|
|
|
DEY ;
|
|
|
|
BEQ MRLP ;
|
|
|
|
|
|
|
|
LDA RAMRD ; if we're still reading from AUX, add 80 back
|
|
|
|
BPL MRLPRTS
|
|
|
|
STA RAMRDOFF ; read from MAIN
|
|
|
|
LDA DESTDA+1
|
|
|
|
CLC
|
2019-10-11 01:27:34 +00:00
|
|
|
ADC #$80
|
2019-07-17 13:52:26 +00:00
|
|
|
STA DESTDA+1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MRLPRTS RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
IMM LDX #$00 ; GET BYTE POINTED AT
|
|
|
|
; BY PROGRAM COUNTER
|
|
|
|
LDA HIPCH ; if HIPCH, get it from AUX
|
|
|
|
BEQ IMM2
|
|
|
|
STA RAMRDON ; AUX on
|
|
|
|
|
|
|
|
IMM2 LDA (PCL,X)
|
|
|
|
STA SRC ; SAVE IT IN SCR
|
|
|
|
LDA #$13 ; MAKE SCR THE SOURCE INDEX
|
|
|
|
STA SPEED ; ??? should SPEED be SCR?
|
|
|
|
STA RAMRDOFF ; back to main
|
|
|
|
JSR INCPC ; BUMP PC
|
|
|
|
LDX #$00 ; POINT TO INTERP PAGE 2
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
ADDR TYA ;
|
|
|
|
EOR FLAG ;
|
|
|
|
TAY ;
|
|
|
|
AND #$0F ;
|
|
|
|
STA SRC ;
|
|
|
|
ROL A ;
|
|
|
|
BVS WOCRY ;
|
|
|
|
EOR PSW ;
|
|
|
|
WOCRY PHA ;
|
|
|
|
LSR A ;
|
|
|
|
LDA ZERO ;
|
|
|
|
AND #$0F ;
|
|
|
|
ADC SRC ;
|
|
|
|
AND #$10 ;
|
|
|
|
STA SRC+1
|
|
|
|
LDA #$EF ;
|
|
|
|
JSR CYAC ;
|
|
|
|
PLA ;
|
|
|
|
LSR A ;
|
|
|
|
TYA ;
|
|
|
|
ADC ZERO ;
|
|
|
|
JMP MVIT1 ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; TABLE OF PSW MASKS
|
|
|
|
MSKTBL DB $80 ; SIGN BIT MASK
|
|
|
|
FOUR DB $04,$01,$40 ; PARITY BIT MASK, CARRY BIT MASK, ZERO BIT MASK
|
|
|
|
|
|
|
|
; XFER TABLE
|
|
|
|
XFERTBL
|
|
|
|
DB >MOVIT,<MOVIT ; MOVIT
|
|
|
|
DB >ROTATE,<ROTATE ; ROTATE
|
|
|
|
DB >MVI,<MVI ; MVI
|
|
|
|
DB >DCR,<DCR ; DCR
|
|
|
|
DB >INR,<INR ; INR
|
|
|
|
DB >INXDCX,<INXDCX ; INXDCX
|
|
|
|
DB >LDSTR,<LDSTR ; LDSTR
|
|
|
|
DB >DADLXI,<DADLXI ; DADLXI
|
|
|
|
DB >NOP,<NOP ; NOP
|
|
|
|
DB >RST,<RST ; RST
|
|
|
|
DB >ARIM,<ARIM ; ARIM
|
|
|
|
DB >PUSH,<PUSH ; PUSH
|
|
|
|
DB >CALL,<CALL ; CALL
|
|
|
|
DB >IO,<IO ; IO
|
|
|
|
DB >JMP,<JMP ; JMP
|
|
|
|
DB >POP,<POP ; POP
|
|
|
|
DB >RETURN,<RETURN ; RETURN
|
|
|
|
DB >CMP,<CMP ; CMP
|
|
|
|
DB >ORA,<ORA ; ORA
|
|
|
|
DB >XRA,<XRA ; XRA
|
|
|
|
DB >ANA,<ANA ; ANA
|
|
|
|
DB >SBB,<SBB ; SBB
|
|
|
|
DB >SUB,<SUB ; SUB
|
|
|
|
DB >ADC,<ADC ; ADC
|
|
|
|
DB >ADD,<ADD ; ADD
|
|
|
|
|
|
|
|
XFERTBL3
|
|
|
|
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF
|
|
|
|
|
|
|
|
L0BA6 DB $FF
|
|
|
|
L0BA7 DB $FF
|
|
|
|
BRKTBL DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
|
|
|
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
INCHPOS INC HPOS ;increment HPOSition = cursor right
|
|
|
|
EDLIN ; edit line of registers?
|
|
|
|
LDA KBDSTROBE ; clear keyboard strobe
|
|
|
|
READKEY2
|
|
|
|
JSR RDKEY ; read key
|
|
|
|
CMP #$95 ; right arrow?
|
|
|
|
BEQ NEXTCHAR ; cursor over 1
|
|
|
|
CMP #$A0 ; SPACE
|
|
|
|
BEQ WRITEKEY ; write space to screen
|
|
|
|
CMP #$8D ; CR
|
|
|
|
BNE BKSPC ;
|
|
|
|
RTS ; if CR, done.
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
BKSPC CMP #$88 ; BACKSPACE? There's no *backspace*? left arrow?
|
|
|
|
BNE CMPKEY ; not left arrow, jump down...
|
|
|
|
DEC HPOS ; decrement cursor position
|
|
|
|
BPL EDLIN ; new line? jump back to read key
|
|
|
|
STX HPOS ; otherwise, store X in cursor position - but where does X come from?
|
|
|
|
BNE INCHPOS ; increment cursor position?
|
|
|
|
CMPKEY TAY ; hold keychar in Y temporarily.
|
|
|
|
AND #$60 ; renders anything 20 30 40 ???
|
|
|
|
BEQ READKEY2 ; if zeroes out, not a number or A-F. ???
|
|
|
|
TYA ; keychar back to A
|
|
|
|
JSR CKNUMS ; if a number or A-F, returns with Carry Set
|
|
|
|
BCC READKEY2 ; carry clear, not a number 0-F, start over
|
|
|
|
TYA ;
|
|
|
|
LDY HPOS ;
|
|
|
|
WRITEKEY
|
|
|
|
STA (CURPOS),Y ; store keystroke on screen.
|
|
|
|
NEXTCHAR ; cursor over 1
|
|
|
|
CPX HPOS ; if X > current HPOS,
|
|
|
|
BCS INCHPOS ; increment HPOS and start over
|
|
|
|
LDA #$FF ; otherwise,
|
|
|
|
STA HPOS ; set HPOS to FF
|
|
|
|
BNE INCHPOS ; then increment to 00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; I/O TABLE
|
|
|
|
; 0/10 = SIO STATUS = for left bank of switches
|
|
|
|
; 1/11 = SIO DATA = to put a byte at lower left of screen
|
|
|
|
|
|
|
|
; 08 = Disk Enable/Status channel
|
|
|
|
; 09 = Disk control/sector position channel
|
|
|
|
; 0A = Disk data channel
|
|
|
|
|
|
|
|
; FF/0F = panel switches
|
|
|
|
|
|
|
|
IOTBLOUT DB >SIOSTATUSOUT,<SIOSTATUSOUT,>SIODATAOUT,<SIODATAOUT
|
|
|
|
DB $C0,$30,$C0,$30,$C0,$30,$C0,$30,$C0,$30,$C0,$30
|
|
|
|
DB >DSKSELECT,<DSKSELECT,>DSKCONTROL,<DSKCONTROL,>DSKWRITE,<DSKWRITE
|
|
|
|
DB $C0,$30,$C0,$30,$C0,$30,$C0,$30
|
|
|
|
DB >DISPLAYBYTES,<DISPLAYBYTES
|
|
|
|
|
|
|
|
IOTBLIN DB >SIOSTATUSIN,<SIOSTATUSIN,>SIODATAIN,<SIODATAIN
|
|
|
|
DB $C0,$30,$C0,$30,$C0,$30,$C0,$30,$C0,$30,$C0,$30
|
|
|
|
DB >DSKSTATUS,<DSKSTATUS,>DSKSECTORIN,<DSKSECTORIN,>DSKREAD,<DSKREAD
|
|
|
|
DB $C0,$30,$C0,$30,$C0,$30,$C0,$30
|
|
|
|
DB >SWITCHBYTES,<SWITCHBYTES
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; SETUP 8080 REGISTERS
|
|
|
|
|
|
|
|
SETUP JSR REGSETUP
|
|
|
|
JSR UPDATESWITCHES ; update the switches in display.
|
|
|
|
|
|
|
|
SEC
|
|
|
|
JSR WAITLED ; wait LED on
|
|
|
|
|
|
|
|
CLC ; clear carry for PCH display
|
|
|
|
JSR UPDATELEDS
|
|
|
|
|
|
|
|
LDA BASICBUFFERLO ; locate buffer start
|
|
|
|
STA $CE
|
|
|
|
LDA BASICBUFFERHI ;
|
|
|
|
STA $CF
|
|
|
|
|
|
|
|
|
|
|
|
; DISPLAY INTERFACE
|
|
|
|
DISPLAYLOOP
|
|
|
|
|
|
|
|
JSR CLRSCRN ;
|
|
|
|
CLC ; clear carry for PCH display
|
|
|
|
JSR UPDATELEDS ; put displaybytes to LED pixels
|
|
|
|
|
|
|
|
BIT KBDSTROBE ;
|
|
|
|
; KEYBOARD INPUT
|
|
|
|
READKEY
|
|
|
|
LDA KBDBUF ;
|
|
|
|
CMP #$A0 ; space
|
|
|
|
BEQ STEP ; to step one cycle at a time
|
|
|
|
CMP #$D3 ; S
|
|
|
|
BEQ STEP ; to step one cycle at a time
|
|
|
|
CMP #$D4 ; T
|
|
|
|
BEQ TKEY ;
|
|
|
|
CMP #$D2 ; R
|
|
|
|
BEQ JMPRKEY ;
|
|
|
|
CMP #$C7 ; G
|
|
|
|
BEQ GKEY ;
|
|
|
|
CMP #$CE ; N
|
|
|
|
BNE CARET ;
|
|
|
|
JMP NEXT
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; DECREMENT COUNTER, EXAMINE
|
|
|
|
CARET CMP #$DE ; CARET ^
|
|
|
|
BNE IKEY ; not ^, check for I
|
|
|
|
LDX #$0A ; 10 ?
|
|
|
|
LDY #$0C ; 13 ?
|
|
|
|
JSR INCDEC ; decrement counter
|
|
|
|
JMP EXAMINE2
|
|
|
|
JMPINSTRUCTIONS
|
|
|
|
JMP SHOWINST
|
|
|
|
JMPDOBRKS
|
|
|
|
JMP DOBRKS ; too much spaghetti
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; I for instructions
|
|
|
|
IKEY CMP #$C9 ; I key
|
|
|
|
BEQ JMPINSTRUCTIONS
|
|
|
|
CMP #$D8 ; X for EXamine
|
|
|
|
BEQ JMPEXAMINE ; reads switches, puts to PC, displays bytes
|
|
|
|
CMP #$D0 ; P for DePosit/PUT
|
|
|
|
BEQ JMPDEPOSIT ; reads switches, puts byte into memory at PC
|
|
|
|
CMP #$CF ; O for depOsit Next
|
|
|
|
BEQ JMPDEPOSITNEXT
|
|
|
|
BNE KKEY ; not O? check for K
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
JMPRKEY JMP RKEY ; spaghetti...
|
|
|
|
|
|
|
|
|
|
|
|
KKEY CMP #$CB ; K key
|
|
|
|
BEQ JMPDOBRKS ; do breakpoint edits
|
|
|
|
|
|
|
|
; not a function key, CHECK IF IT'S a switch key.
|
|
|
|
|
|
|
|
; *** convert keyboaRD ASCII TO HEX, JSR to switch setting
|
|
|
|
JSR ISITHEX ; returns with CARRY SET IF HEX 0-F
|
|
|
|
; and accumulator in Y
|
|
|
|
BCS JMPSWITCH
|
|
|
|
JSR CKINTE ; otherwise check if SCRATCHPAD==key?
|
|
|
|
JMP READKEY ; back to read keys
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
STEP ; flip up swITCH 2, BOTTOM row. "Single Step"
|
|
|
|
LDX #$02 ; switch 2
|
|
|
|
LDY #$01 ; up
|
|
|
|
JSR BOTTOMROW
|
|
|
|
JSR SIM80 ; Do 1 instruction
|
|
|
|
SEC ; set carry for SIMD display
|
|
|
|
|
|
|
|
JSR DISPLAYREGD ; do reg D, then update LEDs
|
|
|
|
|
|
|
|
JSR BOTTOMROWRST ; reset the switch locations
|
|
|
|
JMP DISPLAYLOOP ; update display
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; TRACE MODE
|
|
|
|
TKEY
|
|
|
|
JSR LINE24 ; setup for write to last line
|
|
|
|
BIT KBDSTROBE ; clears out the keyboard
|
|
|
|
|
|
|
|
TKEY2 JSR CLRSCRN ; clears the text screen
|
|
|
|
JSR CTLC ; check for ^C or switch flipping - ^C returns 0
|
|
|
|
BEQ JMPDISPLAY ; ^C, break out and display current PC
|
|
|
|
JSR CKINTE ; otherwise, check scratch register = accumulator - interrupt?
|
|
|
|
JSR SIM80 ; do one instruction
|
|
|
|
|
|
|
|
SEC ; set carry for SIMD display
|
|
|
|
JSR DISPLAYREGD ; do reg D, then update LEDs
|
|
|
|
JSR NEXTPC ;
|
|
|
|
BEQ JMPDISPLAY ; error out on 00 - or is this checking breakpoints?
|
|
|
|
BNE TKEY2 ; else loop for another step
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
; G for GO - RUN MODE
|
|
|
|
GKEY CLC
|
|
|
|
JSR WAITLED ; turn off the WAIT lamp
|
|
|
|
LDA SWITCHBYTES
|
|
|
|
STA SWITCHSCRATCH ; store the switch settings
|
|
|
|
|
|
|
|
JSR LINE24 ; setup for write to last line
|
|
|
|
BIT KBDSTROBE ; clears out the keyboard
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GKEY2 JSR PCHFIX ; WTAF???
|
|
|
|
JSR SIM80 ; do one instruction
|
|
|
|
|
|
|
|
LDX PNT+$01 ; load next instruction PNT Hi???
|
|
|
|
BEQ CTLC2 ; if it's 00 ???
|
|
|
|
|
|
|
|
JSR NEXTPC ; otherwise get next instruction, check for breakpoint
|
|
|
|
BEQ JMPDISPLAY ; if returns 0 jmp out to displayloop
|
|
|
|
CTLC2 CLC
|
|
|
|
JSR STOPG ; check for ^C, don't do switch keys
|
|
|
|
BEQ JMPDISPLAY ; jmp to displayloop on ^C
|
|
|
|
BMI JMPCTRLB ; if sign set, got a ^B
|
|
|
|
|
|
|
|
JSR CKINTE ; check if SCRATCHPAD=accumulator? ck interrupts
|
|
|
|
JMP GKEY2 ;
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
JMPDEPOSIT
|
|
|
|
JMP DEPOSIT
|
|
|
|
|
|
|
|
|
|
|
|
JMPEXAMINE
|
|
|
|
JMP EXAMINE
|
|
|
|
JMPDEPOSITNEXT
|
|
|
|
JMP DEPOSITNEXT
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; REGISTER MODIFY
|
|
|
|
RKEY LDA #$15 ; down to line 21
|
|
|
|
JSR BASCALC ;
|
|
|
|
LDX #$1C ; 28?
|
|
|
|
JSR EDLIN
|
|
|
|
JSR EDITREGS ;
|
|
|
|
|
|
|
|
JMPCTRLB JMP CTRLB ; bload, read file into IOIN
|
|
|
|
|
|
|
|
JMPSWITCH
|
|
|
|
STA KBDSTROBE
|
|
|
|
JSR SETSWITCH ; toggle the switch indicated by ACCUMULATOR
|
|
|
|
JMP DISPLAYLOOP ; back to display/idle mode
|
|
|
|
|
|
|
|
|
|
|
|
JMPDISPLAY LDA TEXTTOP ; came from CTLC
|
|
|
|
BNE STATUSLINE ; possibly coming from full screen terminal
|
|
|
|
; if full screen, TEXTTOP is 0
|
|
|
|
; texttop is 0,
|
|
|
|
JSR SETGR ; need to set GR mode, load lo-res Altair screen
|
|
|
|
JSR ALTAIRSCREEN ;
|
|
|
|
JSR LINE24 ; sets TEXTTOP to 20
|
|
|
|
|
|
|
|
STATUSLINE JSR PRLEGEND ; print REGs legend
|
|
|
|
SEC ; show D register
|
|
|
|
JSR UPDATELEDS ; update LEDs on run mode? slows down too much.
|
|
|
|
LDA SWITCHSCRATCH ; switch bank 1 back to normal
|
|
|
|
STA SWITCHBYTES
|
|
|
|
|
|
|
|
SEC
|
|
|
|
JSR WAITLED ; wait LED on
|
|
|
|
JMP DISPLAYLOOP ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CTLC CLC ; clear carry for checking
|
|
|
|
LDA KBDBUF ; read keyboard for ^C
|
|
|
|
|
|
|
|
; *** convert keyboard ASCII to HEX, JSR to switch setting
|
|
|
|
JSR ISITHEX ; returns with CARRY SET IF HEX 0-F
|
|
|
|
; and accumulator in Y
|
|
|
|
BCC NOSWITCH ; otherwise, check for ^C
|
|
|
|
|
|
|
|
JSR SETSWITCH ; toggle the switch indicated by ACCUMULATOR
|
|
|
|
BIT KBDSTROBE
|
|
|
|
RTS ; and return
|
|
|
|
|
|
|
|
NOSWITCH LDA KBDBUF ; read keyboard for ^C
|
|
|
|
AND #$7F ;
|
|
|
|
CHECKC CMP #$03 ; compare to ^C
|
|
|
|
RTS ; returns with Z bit set (result ZERO) if CTL-C
|
|
|
|
|
|
|
|
STOPG LDA KBDBUF ; read keyboard for ^C
|
|
|
|
AND #$7F ; 0111 1111 - clears high bit.
|
|
|
|
|
|
|
|
CHECKF CMP #$06 ; ^F for full SCREEN
|
|
|
|
BNE CHECKB ; not F, might be B
|
|
|
|
JSR CTRLF ; is F - do fullscreen
|
|
|
|
LDA #$01 ; clears zero bit
|
|
|
|
RTS
|
|
|
|
|
|
|
|
CHECKB CMP #$02 ; CTRL B = load BASIC Program
|
|
|
|
BNE CHECKC ; nope? Check ^C
|
|
|
|
LDA #$FF ; clears zero bit, sets sign bit
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
DOBRKS LDA #$16 ;
|
|
|
|
JSR BASCALC ;
|
|
|
|
LDA #$0E ;
|
|
|
|
STA HPOS ;
|
|
|
|
LDX #$0B ;
|
|
|
|
PRBRK LDA BREAKPOINTS,x ; print "BREAKPOINTS"
|
|
|
|
JSR COUT ;
|
|
|
|
DEX ;
|
|
|
|
BNE PRBRK ;
|
|
|
|
LDA #$17 ; down a line to print addresses
|
|
|
|
JSR BASCALC ;
|
|
|
|
LDX #$00 ;
|
|
|
|
STX HPOS ;
|
|
|
|
LDA PNT+$01 ; pointer+1 == 0?
|
|
|
|
BEQ READREGS ;
|
|
|
|
PRBRKS LDA BRKTBL,X ; print breakpoint addresses
|
|
|
|
JSR PRBYTE ;
|
|
|
|
INX ;
|
|
|
|
TXA ;
|
|
|
|
LSR A ;
|
|
|
|
BCS PRBRKS ;
|
|
|
|
SEC ;
|
|
|
|
SBC PNT+$01 ;
|
|
|
|
BEQ READREGS ;
|
|
|
|
LDA #$A0 ; space
|
|
|
|
JSR COUT ; print space between breakpoints.
|
|
|
|
JMP PRBRKS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
READREGS ; Read in edited registers ???
|
|
|
|
LDX #$26 ;
|
|
|
|
JSR EDLIN ; clear strobe
|
|
|
|
JSR CLREOL ; clear to end of line
|
|
|
|
LDA #$00 ; zero out
|
|
|
|
TAY ;
|
|
|
|
TAX ;
|
|
|
|
STA PNT+$01 ; next instruction = 0 ???
|
|
|
|
STA FLAG ; flag = 0
|
|
|
|
EACHCHAR
|
|
|
|
LDA (CURPOS),Y ; load ACCUMULATOR with char at cursor position
|
|
|
|
CMP #$A1 ; compare with printable ascii (non-space)
|
|
|
|
INY ; next char on line
|
|
|
|
BCC DONELINE ; <A1 is space. skip over.
|
|
|
|
CMP #$BA ; BA=colon
|
|
|
|
BCC ATOHEX ; <BA is a number
|
|
|
|
ADC #$08 ; not a number, add 8 + carry (A=#$41, ==#$4A)
|
|
|
|
ATOHEX AND #$0F ; Get lower nibble (convert ascii to hex)
|
|
|
|
STA SRC ;
|
|
|
|
LDA BRKTBL,X ;
|
|
|
|
ASL A ;
|
|
|
|
ASL A ;
|
|
|
|
ASL A ;
|
|
|
|
ASL A ;
|
|
|
|
ORA SRC ;
|
|
|
|
STA BRKTBL,X ;
|
|
|
|
INC FLAG ;
|
|
|
|
LDA FLAG ;
|
|
|
|
LSR A ;
|
|
|
|
BCS DONELINE ;
|
|
|
|
INX ;
|
|
|
|
TXA ;
|
|
|
|
LSR A ;
|
|
|
|
BCS DONELINE ;
|
|
|
|
INC PNT+$01 ;
|
|
|
|
LDA #$08 ;
|
|
|
|
CMP PNT+$01 ;
|
|
|
|
BEQ DONEREAD ;
|
|
|
|
DONELINE
|
|
|
|
CPY #$27 ; done with full line?
|
|
|
|
BCC EACHCHAR ; nope. go back to next char
|
|
|
|
DONEREAD
|
|
|
|
JMP DISPLAYLOOP ; done reading registers.
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
NEXTPC LDX PNT+$01 ; next instruction
|
|
|
|
BEQ INXRTS ; instruction == 00, NOP?
|
|
|
|
TXA ;
|
|
|
|
ASL A ;
|
|
|
|
TAX ;
|
|
|
|
NEXTPCH LDA PCH ; load counter Hi
|
|
|
|
CMP L0BA6,X ;
|
|
|
|
BNE XMINUS2 ;
|
|
|
|
LDA PCL ;
|
|
|
|
CMP L0BA7,X ;
|
|
|
|
BNE XMINUS2 ;
|
|
|
|
LDY #$73 ;
|
|
|
|
JMP BELL2 ; BEEP! (BREAKPOINT) jump to bell and RTS
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
XMINUS2 DEX ; decrement x
|
|
|
|
DEX ; twice
|
|
|
|
BNE NEXTPCH ; still not zero, ???
|
|
|
|
INXRTS INX ; If ZERO, increment X and RTS
|
|
|
|
RTS ; x=1
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
CKINTE ; chECK FOR CTRL+(P-W) interrupt?
|
|
|
|
CMP SCR ; A == scratchpad?
|
|
|
|
BEQ RTS2 ; yes, RTS
|
|
|
|
STA SCR ; no, store A in scratchpad
|
|
|
|
AND #$60 ; AND 0110 0000 = if zeroes out, not a number or A-F. ???
|
|
|
|
BNE RTS2 ; both bits zero, RTS
|
|
|
|
LDA KBDBUF ; otherwise load KEYBOARD
|
|
|
|
ASL A ; shift left?
|
|
|
|
ASL A ; multiply by 2
|
|
|
|
ASL A ; three times.
|
|
|
|
CMP #$B9 ; 1011 1001
|
|
|
|
BCS RTS2 ; greater than #$B9 == ctrl+(P-W) key set for reset
|
|
|
|
STA PNT ; pointer to reset target for interrupt 0-7
|
|
|
|
RTS2 RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
; SETUP 8080 REGISTERS
|
|
|
|
REGSETUP
|
|
|
|
LDX #$00 ; ZERO
|
|
|
|
|
|
|
|
STX PNT+$01 ; pointer Hi
|
|
|
|
STX PNT ; pointer Lo
|
|
|
|
STX PCL ; PC LO
|
|
|
|
STX PCH ; PC HI ****
|
|
|
|
STX HIPCH ; is PCH above $7F?
|
|
|
|
STX SCR ; scratchpad
|
|
|
|
STX SIODATAIN ; clear SIO DATA for use
|
|
|
|
STX SIODATAOUT ; clear SIO DATA for use
|
|
|
|
INX ; ONE
|
|
|
|
STX INTE ; Interrupt enable = 1
|
|
|
|
INX ; TWO
|
|
|
|
STX PSW ; processor status = 00000010
|
|
|
|
|
|
|
|
LDX #$FF ; $11-$12 == #$ff
|
|
|
|
STX DECIT ;
|
|
|
|
STX DECIT+$01 ;
|
|
|
|
STX SPL
|
|
|
|
INX ;
|
|
|
|
STX INCIT+$01 ; $13-$14 == #$00
|
|
|
|
STX HPOS ; cursor to 0
|
|
|
|
INX ;
|
|
|
|
STX INCIT ; $13-$14 == 01 00
|
|
|
|
|
|
|
|
LDX #$0F
|
|
|
|
STX SPH
|
|
|
|
|
|
|
|
RTS ; 0E74 60
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
DSKSPIN LDX DSKSECTOR ; looking for a specific sector, but no way to tell which one
|
|
|
|
INX ; increment DSKSECTOR through #$1F
|
|
|
|
|
|
|
|
CPX #$20 ; SECTOR 32
|
|
|
|
BEQ RESETTRACKPOINTER ; set everything to 00
|
|
|
|
|
|
|
|
STX DSKSECTOR ; set new DSKSECTOR
|
|
|
|
TXA ; into ACCUMULATOR
|
|
|
|
CLC
|
|
|
|
|
|
|
|
SETSECTORIN ROL ; ROL and set as DSKSECTORIN
|
|
|
|
STA DSKSECTORIN ; bit 0 always low == sector TRUE (ready to read/write)
|
|
|
|
|
|
|
|
LDA TRACKPOINTER ; add 137 bytes to TRACKPOINTER
|
|
|
|
CLC
|
|
|
|
ADC #$89 ; add 137
|
|
|
|
STA TRACKPOINTER
|
|
|
|
BCC DSKSPIN2
|
|
|
|
INC TRACKPOINTER+1
|
|
|
|
DSKSPIN2 LDA #$00 ; reset to read/write at beginning of next sector
|
|
|
|
STA SECTOROFFSET
|
|
|
|
RTS
|
|
|
|
|
|
|
|
RESETTRACKPOINTER LDA BASICBUFFERLO
|
|
|
|
STA TRACKPOINTER
|
|
|
|
LDA BASICBUFFERHI
|
|
|
|
STA TRACKPOINTER+1
|
|
|
|
LDA #$00
|
|
|
|
STA DSKSECTOR
|
|
|
|
STA DSKSECTORIN
|
|
|
|
STA SECTOROFFSET
|
|
|
|
RTS
|
|
|
|
|
|
|
|
DSKIN ; get data from virtual DSK track
|
|
|
|
LDY SECTOROFFSET ; which byte to grab
|
|
|
|
LDA TRACKPOINTER
|
|
|
|
STA $0
|
|
|
|
LDA TRACKPOINTER+1
|
|
|
|
STA $1
|
|
|
|
LDA ($0),Y ; grab byte from track pointer + offset
|
|
|
|
STA DSKREAD
|
|
|
|
INC SECTOROFFSET ; ready for next read
|
|
|
|
RTS
|
|
|
|
|
|
|
|
; virtual serial interface
|
|
|
|
SIOOUT ; JUST GOT A BYTE FROM SIM80
|
|
|
|
LDA SRC ; if output is 00, setting status.
|
|
|
|
BEQ SIORTS ; 00 -> ignore for now
|
|
|
|
|
|
|
|
AND #$0F ; 1x => 0x
|
|
|
|
CMP #$01 ; is it on port 1 or 11?
|
|
|
|
BNE DSKOUT ; if not, is it output to DSK?
|
|
|
|
|
|
|
|
; LOAD BYTE FROM SIODATA
|
|
|
|
LDA SIODATAOUT ; load SIO DATA
|
|
|
|
|
|
|
|
; translate CR/LF into newline.
|
|
|
|
; CR = 0D
|
|
|
|
; LF = 0A
|
|
|
|
CMP #$0A
|
|
|
|
BEQ SIORTS ; ignore LF, just do CR.
|
|
|
|
|
|
|
|
ORA #$80 ; add the high bit?
|
|
|
|
|
|
|
|
|
|
|
|
; OUTPUT TO SCREEN
|
|
|
|
JSR COUT ; output char
|
|
|
|
|
|
|
|
SIORTS SEC
|
|
|
|
RTS
|
|
|
|
|
|
|
|
SIOIN ; SIGNALLED FROM IOIN THAT SIM80 LOOKING FOR A BYTE.
|
|
|
|
; looking for a byte from IN 1 or 0?
|
|
|
|
LDX #$00
|
|
|
|
LDA SRC ; if input is 00, checking SIO status.
|
|
|
|
|
|
|
|
CMP #$ff ; sense switches.
|
|
|
|
BEQ SENSEIN
|
|
|
|
|
|
|
|
CMP #$0A ; looking for DISK DATA
|
|
|
|
BEQ DSKIN
|
|
|
|
|
|
|
|
CMP #$09 ; looking for DISK SECTOR
|
|
|
|
BEQ DSKSPIN ; "spin" the disk
|
|
|
|
|
|
|
|
CMP #$10 ; SIO2 on port 10/11. SIO1 on port 0/1
|
|
|
|
BCC SIO1IN
|
|
|
|
INX
|
|
|
|
INX ; use SIO2 status bytes instead of SIO1
|
|
|
|
JMP SIO2IN
|
|
|
|
|
|
|
|
SIO1IN ;AND #$0F ; kill hi nibble so 10==00
|
|
|
|
BNE SIOKEY ; 00? status check. Otherwise, expects a byte.
|
|
|
|
STA SIODATAIN ; clear the pipes on status check, 00 to data
|
|
|
|
JMP SIOREADY ; set status to ready for I/O
|
|
|
|
|
|
|
|
; CHECK KEYBOARD
|
|
|
|
SIOKEY LDA KBDBUF ; read keyboard
|
|
|
|
STA KBDSTROBE ; clear strobe
|
|
|
|
|
|
|
|
; IF KEY WAITING, LOAD IT IN SIODATA
|
|
|
|
BPL SIORTS ; no key. RTS.
|
|
|
|
; BPL CHECKKSW ; if bit8/carry, has keyboard input. else check for BASIC LOAD
|
|
|
|
STA SIODATAIN ; put ascii in DATA
|
|
|
|
|
|
|
|
; SET SIOSTATUS TO 00 = HAVE DATA
|
|
|
|
LDA SIOSTATUSBYTES,X ; set STATUS to 00 - HAVE DATA/READY FOR OUTPUT
|
|
|
|
STA SIOSTATUSIN
|
|
|
|
RTS
|
|
|
|
|
|
|
|
; NO KEY WAITING
|
|
|
|
; SET SIOSTATUS 01 = STILL WAITING INPUT
|
|
|
|
;CHECKKSW JSR KSW ; CHECK FOR KSW INPUT FROM BASIC LOAD
|
|
|
|
; ; should only run on input and if src = 1?
|
|
|
|
; BPL SIORESET ; if high bit set, have a byte from BASIC LOAD. otherwise, return
|
|
|
|
|
|
|
|
SIOREADY ; SET SIOSTATUS TO 00 = HAVE DATA
|
|
|
|
LDA SIOSTATUSBYTES,X ; set STATUS to 00 - HAVE DATA/READY FOR OUTPUT
|
|
|
|
STA SIOSTATUSIN
|
|
|
|
RTS
|
|
|
|
|
|
|
|
SIORESET INX
|
|
|
|
LDA SIOSTATUSBYTES,X ; 01 = WAITING FOR INPUT/READY FOR OUTPUT
|
|
|
|
STA SIOSTATUSIN ;
|
|
|
|
RTS
|
|
|
|
|
|
|
|
SENSEIN AND #$0F
|
|
|
|
CLC
|
|
|
|
ROL
|
|
|
|
TAY
|
|
|
|
LDA IOTBLIN,Y ; sense switches up/down don't have an IN/OUT version
|
|
|
|
STA DESTDA+1
|
|
|
|
INY
|
|
|
|
LDA IOTBLIN,Y
|
|
|
|
STA DESTDA
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
SIO2IN AND #$0F ; #$10 -> #$00
|
|
|
|
BEQ SIO2STATUS
|
|
|
|
; SIO2 data input
|
|
|
|
LDA KBDBUF ; get the key
|
|
|
|
STA KBDSTROBE ; clear the strobe
|
|
|
|
STA SIODATAIN ; store it in datain buffer
|
|
|
|
JMP SIORESET ; input done. set status to waiting for next check.
|
|
|
|
|
|
|
|
|
|
|
|
SIO2STATUS ; looking for status of SIO2 - have a byte, byte sent, or 00 waiting
|
|
|
|
LDA KBDBUF ; if KBDBUF bit 8 hi, have a byte
|
|
|
|
BPL SIORESET ; bit8 lo, set status to byte sent/waiting
|
|
|
|
JMP SIOREADY ; bit 8 hi, has keyboard input.
|
|
|
|
|
|
|
|
DSKOUT CMP #$0A ; port 0A -> output to DSK
|
|
|
|
BNE SIORTS ; not 0A? -> ignore
|
|
|
|
|
|
|
|
LDY SECTOROFFSET ; which byte of the current sector to push to
|
|
|
|
LDA TRACKPOINTER ; offset within track ($89xSECTOR)
|
|
|
|
STA $0
|
|
|
|
LDA TRACKPOINTER+1
|
|
|
|
STA $1
|
|
|
|
LDA DSKWRITE ; load the byte
|
|
|
|
STA ($0),Y ; set byte at track pointer + offset
|
|
|
|
INC SECTOROFFSET ; ready for next read
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
FULLSCREEN ASC " FULL SCREEN MODE: CONTROL-C TO EXIT ",00
|
|
|
|
LASTLINEBUF DS 41,$00 ; 40 bytes to store last line of split screen text. followed by zero to stop.
|
|
|
|
|
|
|
|
CTRLF LDA TEXTTOP ; control-F for full-screen terminal
|
|
|
|
BEQ CTRLFRTS ; already in full-screen. ignore.
|
|
|
|
|
|
|
|
LDX #$27 ; copy last line of text from $7d0
|
|
|
|
BUFFERLINE LDA $7D0,X
|
|
|
|
STA LASTLINEBUF,X
|
|
|
|
DEX
|
|
|
|
BPL BUFFERLINE
|
|
|
|
|
|
|
|
BIT TXTSET ; set text Mode
|
|
|
|
LDA #$00
|
|
|
|
STA TEXTTOP ; to make scroll full screen.
|
|
|
|
JSR HOME ; clear low res screen
|
|
|
|
|
|
|
|
; Ask for 80 columns?
|
|
|
|
JSR ASK80 ; Returns with ZERO on YES
|
|
|
|
BNE CTRLFGO
|
|
|
|
LDA #$00 ; clears out the Y/N from accumulator
|
|
|
|
JSR $C300
|
|
|
|
|
|
|
|
CTRLFGO LDY #$3F
|
|
|
|
JSR $FE86
|
|
|
|
|
|
|
|
LDA #$00
|
|
|
|
STA $F3 ; no blinking text?
|
|
|
|
|
|
|
|
LDY #>FULLSCREEN
|
|
|
|
LDA #<FULLSCREEN
|
|
|
|
JSR STROUT ;Y=String ptr high, A=String ptr low
|
|
|
|
JSR CROUT
|
|
|
|
|
|
|
|
LDY #$FF
|
|
|
|
JSR $FE86
|
|
|
|
|
|
|
|
LDY #>LASTLINEBUF
|
|
|
|
LDA #<LASTLINEBUF
|
|
|
|
JSR STROUT ;Y=String ptr high, A=String ptr low
|
|
|
|
JSR CROUT
|
|
|
|
|
|
|
|
CTRLFRTS RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LINE24 LDA #$17 ; put cursor at line 24
|
|
|
|
STA VPOS
|
|
|
|
JSR VTAB
|
|
|
|
LDA #$00 ; beginning of line
|
|
|
|
STA HPOS
|
|
|
|
LDA #$14 ; scroll window only lines 20-24
|
|
|
|
STA TEXTTOP
|
|
|
|
RTS
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ASK80STRING ASC "80 COLUMN MODE, Y/N?",00
|
|
|
|
|
|
|
|
ASK80 LDY #>ASK80STRING
|
|
|
|
LDA #<ASK80STRING
|
|
|
|
JSR STROUT ;Y=String ptr high, A=String ptr low
|
|
|
|
JSR CROUT
|
|
|
|
BIT KBDSTROBE ; clear ^F out of buffer
|
|
|
|
|
|
|
|
ASK80LOOP LDA KBDBUF ; check for keydown
|
|
|
|
AND #$80 ; high bit set?
|
|
|
|
BNE ASK80YN ;
|
|
|
|
JMP ASK80LOOP ; got a key?
|
|
|
|
ASK80YN LDA KBDBUF
|
|
|
|
STA KBDSTROBE
|
|
|
|
CMP #$D9 ; Y
|
|
|
|
STA KBDSTROBE
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
EDITREGS
|
|
|
|
LDY #$00 ;
|
|
|
|
JSR SETREG ;
|
|
|
|
STA PSW ;
|
|
|
|
INY ;
|
|
|
|
JSR SETREG ;
|
|
|
|
STA SIMA ;
|
|
|
|
INY ;
|
|
|
|
JSR SETLOHI ;
|
|
|
|
STA SIMC ;
|
|
|
|
STX SIMB ;
|
|
|
|
INY ;
|
|
|
|
JSR SETLOHI ;
|
|
|
|
STA SIME ;
|
|
|
|
STX SIMD ;
|
|
|
|
INY ;
|
|
|
|
JSR SETLOHI ;
|
|
|
|
STA SIML ;
|
|
|
|
STX SIMH ;
|
|
|
|
INY ;
|
|
|
|
JSR SETLOHI ;
|
|
|
|
STA SPL ;
|
|
|
|
STX SPH ;
|
|
|
|
INY ;
|
|
|
|
JSR SETLOHI ;
|
|
|
|
STA PCL ;
|
|
|
|
STX PCH ;
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
SETLOHI
|
|
|
|
JSR SETREG ;
|
|
|
|
SETREG TAX ;
|
|
|
|
LDA #$01 ;
|
|
|
|
STA FLAG ;
|
|
|
|
LDA #$00 ;
|
|
|
|
SETSRC STA SRC ;
|
|
|
|
LDA (CURPOS),Y ;
|
|
|
|
INY ;
|
|
|
|
CMP #$BA ;
|
|
|
|
BCC ATOHEX2 ;
|
|
|
|
ADC #$08 ;
|
|
|
|
ATOHEX2 AND #$0F ; ASCII 0-F to hex
|
|
|
|
ADC SRC ;
|
|
|
|
DEC FLAG ;
|
|
|
|
BNE RTS3 ;
|
|
|
|
ASL A ;
|
|
|
|
ASL A ;
|
|
|
|
ASL A ;
|
|
|
|
ASL A ;
|
|
|
|
BCC SETSRC ;
|
|
|
|
RTS3 RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
PCHFIX
|
|
|
|
; **** add $10 to PCH
|
|
|
|
CLC
|
|
|
|
LDA PCH
|
|
|
|
ADC #$10
|
|
|
|
STA PCH
|
|
|
|
; ****
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
|
|
|
|
CMP #$8F ; if HIPCH, read from AUX
|
|
|
|
BCC PCHFIX2
|
|
|
|
STA RAMRDON
|
|
|
|
SBC #$80
|
|
|
|
STA PCH
|
|
|
|
LDA #$01
|
|
|
|
STA HIPCH
|
|
|
|
|
|
|
|
PCHFIX2 LDA (PCL),Y ; print registers values
|
|
|
|
|
|
|
|
STA OPCODE ;
|
|
|
|
|
|
|
|
LDA HIPCH
|
|
|
|
BEQ PCHFIX3
|
|
|
|
STA RAMRDOFF
|
|
|
|
CLC
|
|
|
|
LDA PCH
|
|
|
|
ADC #$80
|
|
|
|
STA PCH
|
|
|
|
|
|
|
|
; **** subtract $10 from PCH
|
|
|
|
PCHFIX3 SEC
|
|
|
|
LDA PCH
|
|
|
|
SBC #$10
|
|
|
|
STA PCH
|
|
|
|
; ****
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; CLEAR AND REDRAW SCREEN
|
|
|
|
CLRSCRN
|
|
|
|
LDX #$00 ;
|
|
|
|
PRREGS
|
|
|
|
LDY #$00 ;
|
|
|
|
STY HPOS ; back to left side to
|
|
|
|
|
|
|
|
; **** add $10 to PCH
|
|
|
|
CLC
|
|
|
|
LDA PCH
|
|
|
|
ADC #$10
|
|
|
|
STA PCH
|
|
|
|
; ****
|
|
|
|
STA DISPLAYBYTES ; high byte to first bank of LEDs.
|
|
|
|
|
|
|
|
CMP #$8F ; if HIPCH, read from AUX
|
|
|
|
BCC PROPCODE
|
|
|
|
STA RAMRDON
|
|
|
|
SBC #$80
|
|
|
|
STA PCH
|
|
|
|
LDA #$01
|
|
|
|
STA HIPCH
|
|
|
|
|
|
|
|
PROPCODE LDA (PCL),Y ; print registers values
|
|
|
|
|
|
|
|
STA OPCODE ;
|
|
|
|
|
|
|
|
LDA HIPCH
|
|
|
|
BEQ PROPCODE2
|
|
|
|
STA RAMRDOFF
|
|
|
|
CLC
|
|
|
|
LDA PCH
|
|
|
|
ADC #$80
|
|
|
|
STA PCH
|
|
|
|
|
|
|
|
; **** subtract $10 from PCH
|
|
|
|
PROPCODE2 SEC
|
|
|
|
LDA PCH
|
|
|
|
SBC #$10
|
|
|
|
STA PCH
|
|
|
|
; ****
|
|
|
|
|
|
|
|
LDA #$15 ; move cursor to line 22
|
|
|
|
JSR BASCALC ;
|
|
|
|
LDA PSW ;
|
|
|
|
JSR PRREG ; PS = Processor Status byte
|
|
|
|
LDA SIMA ;
|
|
|
|
JSR PRREG ; AC = Accumulator
|
|
|
|
LDA SIMB ;
|
|
|
|
LDX SIMC ;
|
|
|
|
JSR PRLOHI ; BC = B & C Registers
|
|
|
|
LDA SIMD ;
|
|
|
|
LDX SIME ;
|
|
|
|
JSR PRLOHI ; DE = D & E Registers
|
|
|
|
LDA SIMH ;
|
|
|
|
LDX SIML ;
|
|
|
|
JSR PRLOHI ; HL = H and L Registers
|
|
|
|
LDA SPH ;
|
|
|
|
LDX SPL ;
|
|
|
|
JSR PRLOHI ; SP = Stack Pointer HiLo
|
|
|
|
LDA PCH ;
|
|
|
|
LDX PCL ;
|
|
|
|
JSR PRLOHI ; PC = SIM80 Program Counter Hi and Lo
|
|
|
|
LDA OPCODE ;
|
|
|
|
JSR PRREG ; OP = current opcode
|
|
|
|
LDA #$01 ;
|
|
|
|
CMP INTE ; INTE = Interrupt Enable (IE)
|
|
|
|
BNE BRKYN ; not 1, set zero for output.
|
|
|
|
LDA #$00 ;
|
|
|
|
BRKYN JSR PRREG ; Y or N on breakpoints
|
|
|
|
LDA #$CE ;
|
|
|
|
LDX PNT+$01 ;
|
|
|
|
BEQ BRKPTS ;
|
|
|
|
LDA #$59 ;
|
|
|
|
BRKPTS JSR COUT ;
|
|
|
|
|
|
|
|
GRABLEDS
|
|
|
|
LDX PCL ;
|
|
|
|
STX DISPLAYBYTES+1
|
|
|
|
LDA OPCODE ;
|
|
|
|
STA DISPLAYBYTES+2
|
|
|
|
|
|
|
|
RTS
|
|
|
|
;/CLRSCRN
|
|
|
|
|
|
|
|
PRLEGEND LDA #$14 ; down to line 20
|
|
|
|
JSR BASCALC
|
|
|
|
LDX #$00
|
|
|
|
STX HPOS
|
|
|
|
NEXTLEGEND LDA LEGEND,x ;
|
|
|
|
JSR COUT ;
|
|
|
|
INX ;
|
|
|
|
CPX #$27 ;
|
|
|
|
BNE NEXTLEGEND ;
|
|
|
|
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
; Display bytes as LEDS
|
|
|
|
UPDATELEDS BCC DISPLAYPCH ; carry clear, show PCH
|
|
|
|
|
|
|
|
DISPLAYREGD ;LDA DISPLAYBYTES ; carry set, show SIMD
|
|
|
|
BCS STABYTE
|
|
|
|
DISPLAYPCH LDA PCH
|
|
|
|
STA DISPLAYBYTES ; DISPLAY LAST MEMORY ACCESS (LDAX/STAX/ETC) WHILE TRACE
|
|
|
|
STABYTE
|
|
|
|
JSR GRABLEDS ; update display bytes from registers.
|
|
|
|
LDA #$01 ; down one row to use COUT
|
|
|
|
JSR BASCALC
|
|
|
|
LDA #$16 ; over 22 for COUT
|
|
|
|
STA HPOS
|
|
|
|
|
|
|
|
LDX #$02 ; opcode byte
|
|
|
|
JSR BYTELOOP
|
|
|
|
|
|
|
|
LDA #$03 ; down one row to use COUT
|
|
|
|
JSR BASCALC
|
|
|
|
LDA #$06 ; over 22 for COUT
|
|
|
|
STA HPOS
|
|
|
|
|
|
|
|
LDX #$00 ; PC HI
|
|
|
|
JSR BYTELOOP
|
|
|
|
|
|
|
|
LDX #$01 ; PC LO
|
|
|
|
JSR BYTELOOP
|
|
|
|
|
|
|
|
RTS ; DONE DISPLAYING
|
|
|
|
|
|
|
|
NEXT JSR INCPC ; next instruction
|
|
|
|
LDY #$00 ; down
|
|
|
|
JMP EXAMINE2
|
|
|
|
EXAMINE
|
|
|
|
LDY #$01 ; up
|
|
|
|
LDA SWITCHBYTES
|
|
|
|
STA PCH
|
|
|
|
LDA SWITCHBYTES+1
|
|
|
|
STA PCL
|
|
|
|
EXAMINE2
|
|
|
|
LDX #$03 ; switch 3
|
|
|
|
JSR BOTTOMROW
|
|
|
|
JSR BOTTOMROWRST ; reset the switch locations
|
|
|
|
JMP DISPLAYLOOP ; back to read keys
|
|
|
|
|
|
|
|
|
|
|
|
DEPOSITNEXT
|
|
|
|
JSR INCPC ; increment program counter, then dePosit
|
|
|
|
LDY #$00 ; up
|
|
|
|
JMP DEPSW
|
|
|
|
DEPOSIT
|
|
|
|
LDY #$01 ; up
|
|
|
|
DEPSW LDX #$04 ; switch 4
|
|
|
|
JSR BOTTOMROW
|
|
|
|
|
|
|
|
CLC ; add 10 to PCH before deposit
|
|
|
|
LDA PCH
|
|
|
|
ADC #$10
|
|
|
|
STA PCH
|
|
|
|
|
|
|
|
LDX #$00
|
|
|
|
LDA SWITCHBYTES+1
|
|
|
|
STA (PCL,X) ;
|
|
|
|
|
|
|
|
SEC ; subtract 10 after
|
|
|
|
LDA PCH
|
|
|
|
SBC #$10
|
|
|
|
STA PCH
|
|
|
|
|
|
|
|
JSR BOTTOMROWRST ; reset the switch locations
|
|
|
|
CLC ; clear carry for PCH display
|
|
|
|
JSR UPDATELEDS
|
|
|
|
JMP DISPLAYLOOP ; back to read keys
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ISITHEX
|
|
|
|
TAY ; hold keychar in Y.
|
|
|
|
AND #$60 ; renders anything 20 30 40 ???
|
|
|
|
BEQ DONEHEX ; if zeroes out, not a number or A-F. ???
|
|
|
|
TYA ; keychar back to A
|
|
|
|
JSR CKNUMS ; if a number or A-F, returns with Carry Set
|
|
|
|
BCC DONEHEX ; carry clear, not a number 0-F, start over
|
|
|
|
DONEHEX RTS
|
|
|
|
|
|
|
|
|
|
|
|
CKNUMS EOR #$B0 ; B0 = ascii 0,
|
|
|
|
CMP #$0A ; compare to 10, number from 0 - 9
|
|
|
|
BCC SETCARRY ; set carry and RTS (is a number)
|
|
|
|
ADC #$88 ;
|
|
|
|
CMP #$FA ; < FA not a letter A-F
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
SETCARRY
|
|
|
|
SEC ;
|
|
|
|
RTS ;
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
|
|
SETSWITCH
|
|
|
|
TYA ; Y back to accum.
|
|
|
|
CMP #$BA ; BA=colon
|
|
|
|
BCC ATOHEX3 ; <BA is a number
|
|
|
|
ADC #$08 ; not a number, add 8 + carry (A=#$41, ==#$4A)
|
|
|
|
ATOHEX3 AND #$0F ; Get lower nibble (convert ascii to hex)
|
|
|
|
|
|
|
|
TAX ; A becomes loop number to set switch bit.
|
|
|
|
INX ; 0 becomes 1 (loop)
|
|
|
|
|
|
|
|
WHICHBANK CMP #$08 ; A >/= 8, and we do SWITCHBYTES+0 carry set
|
|
|
|
LDA #$00 ; A < 8, and we do SWITCHBYTES+1 carry clear
|
|
|
|
|
|
|
|
ADC #$00 ; if carry, 0. If not, 1
|
|
|
|
EOR #$01 ; flip bit 1
|
|
|
|
|
|
|
|
CMP #$01 ; carry set, >7, so needs an extra loop
|
|
|
|
BCS SETBANK ; carry clear, 0-7
|
|
|
|
|
|
|
|
INX
|
|
|
|
SETBANK TAY ; bank 0 or 1
|
|
|
|
|
|
|
|
SEC ; set carry bit to rotate into accumulator
|
|
|
|
LDA #$00
|
|
|
|
ROTATEIN ROL ; rotate the bit into
|
|
|
|
DEX
|
|
|
|
BNE ROTATEIN
|
|
|
|
|
|
|
|
EOR SWITCHBYTES,Y
|
|
|
|
STA SWITCHBYTES,Y
|
|
|
|
|
|
|
|
JSR UPDATESWITCHES ; update the display
|
|
|
|
|
|
|
|
RTS
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
; Display bytes as sWITCHES
|
|
|
|
UPDATESWITCHES
|
|
|
|
BIT SPKR ; click
|
|
|
|
|
|
|
|
LDA #$06 ; down row to use COUT
|
|
|
|
JSR BASCALC
|
|
|
|
LDA #$06 ; over for COUT
|
|
|
|
STA HPOS
|
|
|
|
LDX #$00 ; PC HI
|
|
|
|
JSR SWITCHLOOP
|
|
|
|
|
|
|
|
LDA #$06 ; down row to use COUT
|
|
|
|
JSR BASCALC
|
|
|
|
|
|
|
|
LDX #$01 ; PC LO
|
|
|
|
JSR SWITCHLOOP
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
SWITCHLOOP LDY #$08 ; do a byte's worth
|
|
|
|
LDA SWITCHBYTES,X ; put the switch status into scratch
|
|
|
|
STA SWITCHSCRATCH,X
|
|
|
|
SWLOOP LDA #$AA ; gray
|
|
|
|
JSR COUT ; output gray between switches
|
|
|
|
LDA #$25 ; switch DOWN
|
|
|
|
CLC ; clear carry
|
|
|
|
ROL SWITCHSCRATCH,X ; rotate opcode, hi bit into carry
|
|
|
|
BCC SETSW ; if Carry clear, skip
|
|
|
|
LDA #$26 ; switch UP
|
|
|
|
SETSW JSR COUT ; output to screen
|
|
|
|
DEY ; done all 8 bits?
|
|
|
|
BNE SWLOOP
|
|
|
|
; bottom pixels
|
|
|
|
|
|
|
|
LDA SWITCHBYTES,X ; put the switch status into scratch
|
|
|
|
STA SWITCHSCRATCH,X
|
|
|
|
|
|
|
|
LDA #$07 ; down row to use COUT
|
|
|
|
JSR BASCALC
|
|
|
|
LDA HPOS ; over for COUT
|
|
|
|
SEC
|
|
|
|
SBC #$10
|
|
|
|
STA HPOS
|
|
|
|
|
|
|
|
SWITCHLOOP2 LDY #$08 ; do a byte's worth
|
|
|
|
LDA SWITCHBYTES,X ; put the switch status into scratch
|
|
|
|
STA SWITCHSCRATCH,X
|
|
|
|
SWLOOP2 LDA #$AA ; gray
|
|
|
|
JSR COUT ; output gray between switches
|
|
|
|
LDA #$A6 ; switch DOWN
|
|
|
|
CLC ; clear carry
|
|
|
|
ROL SWITCHSCRATCH,X ; rotate opcode, hi bit into carry
|
|
|
|
BCC SETSW2 ; if Carry clear, skip
|
|
|
|
LDA #$A5 ; switch UP
|
|
|
|
SETSW2 JSR COUT ; output to screen
|
|
|
|
DEY ; done all 8 bits?
|
|
|
|
BNE SWLOOP2
|
|
|
|
BIT SPKR ; click
|
|
|
|
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
|
|
BYTELOOP LDY #$08 ; do a byte's worth
|
|
|
|
BITLOOP LDA #$AA ; gray
|
|
|
|
JSR COUT ; output gray between lights
|
|
|
|
LDA #$A8 ; LED OFF
|
|
|
|
CLC ; clear carry
|
|
|
|
ROL DISPLAYBYTES,X ; rotate opcode, hi bit into carry
|
|
|
|
BCC SETLED ; if Carry clear, skip
|
|
|
|
LDA #$A1 ; LED ON
|
|
|
|
SETLED JSR COUT ; output to screen
|
|
|
|
DEY ; done all 8 bits?
|
|
|
|
BNE BITLOOP
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
WAITLED LDY #$A8 ; light off
|
|
|
|
BCC SETWAIT ; Carry clear, lamp off
|
|
|
|
LDY #$A1 ; Carry set, light on
|
|
|
|
SETWAIT LDA #$03 ; down one row to use COUT
|
|
|
|
JSR BASCALC
|
|
|
|
LDA #$02 ; over 22 for COUT
|
|
|
|
STA HPOS
|
|
|
|
TYA
|
|
|
|
JSR COUT ; output to screen
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
|
|
BOTTOMROW ; flip switches
|
|
|
|
|
|
|
|
; six switches X = number of loops
|
|
|
|
; Y =1 for up, =0 for down.
|
|
|
|
BIT SPKR ; click
|
|
|
|
LDA #$04 ; start at column 4
|
|
|
|
STA HPOS
|
|
|
|
BRSWLOOP ; bottom row switch loop.
|
|
|
|
INC HPOS
|
|
|
|
INC HPOS ; over two spaces
|
|
|
|
INC HPOS ; over two spaces
|
|
|
|
DEX ; loop X times
|
|
|
|
BNE BRSWLOOP ; switch last one up/down
|
|
|
|
|
|
|
|
LDA #$0A ; row 10
|
|
|
|
JSR BASCALC
|
|
|
|
LDA #$55 ; #$55 is down
|
|
|
|
CPY #$0 ; is Y 0 or 1?
|
|
|
|
BEQ SWDOWN1
|
|
|
|
LDA #$52 ; #$52 is up
|
|
|
|
|
|
|
|
SWDOWN1 JSR COUT ; put switch pixels
|
|
|
|
|
|
|
|
LDA #$0B ; Down to row 11
|
|
|
|
JSR BASCALC
|
|
|
|
DEC HPOS ; back over 1 px
|
|
|
|
LDA #$A2 ; #$A2 is down
|
|
|
|
CPY #$0 ; is Y 0 or 1?
|
|
|
|
BEQ SWDOWN2
|
|
|
|
LDA #$A5 ; #$A5 is up/center
|
|
|
|
SWDOWN2 JSR COUT ; put switch pixels
|
|
|
|
|
|
|
|
BIT SPKR ; click
|
|
|
|
LDA #$80
|
|
|
|
JSR WAIT ; delay to show switch action.
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOTTOMROWRST
|
|
|
|
LDX #$04 ; four of six switches X = number of loops
|
|
|
|
LDA #$05 ; start at column 4
|
|
|
|
STA HPOS
|
|
|
|
BRRSLOOP
|
|
|
|
LDA #$0A ; row 10
|
|
|
|
JSR BASCALC
|
|
|
|
|
|
|
|
INC HPOS
|
|
|
|
INC HPOS ; over two spaces
|
|
|
|
|
|
|
|
LDA #$25 ; #$25 is centered
|
|
|
|
JSR COUT ; put switch pixels
|
|
|
|
|
|
|
|
LDA #$0B ; Down to row 11
|
|
|
|
JSR BASCALC
|
|
|
|
DEC HPOS ; back over 1 px
|
|
|
|
|
|
|
|
LDA #$A5 ; #$A5 is center
|
|
|
|
JSR COUT ; put switch pixels
|
|
|
|
|
|
|
|
DEX ; loop X times
|
|
|
|
BNE BRRSLOOP ; switch last one up/down
|
|
|
|
|
|
|
|
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
|
|
PRLOHI JSR PRBYTE ; prints a pair of registers
|
|
|
|
TXA ;
|
|
|
|
PRREG JSR PRBYTE ; print hex of one register, followed by space (#$A0)
|
|
|
|
LDA #$A0 ;
|
|
|
|
JMP $FDED ; JMP to COUT with RTS ?
|
|
|
|
|
|
|
|
MOVETXT ; move the current text page to alt text page
|
|
|
|
LDA #$00 ; Setup pointers to move memory
|
|
|
|
STA $3C ; $3C and $3D for source start
|
|
|
|
LDA #$04
|
|
|
|
STA $3D
|
|
|
|
|
|
|
|
LDA #$FF
|
|
|
|
STA $3E ; $3E and $3F for source end
|
|
|
|
LDA #$07
|
|
|
|
STA $3F ;
|
|
|
|
|
|
|
|
LDA #$00
|
|
|
|
STA $42 ; $42 and $43 for destination
|
|
|
|
LDA #$08 ; $1000 == destination
|
|
|
|
STA $43
|
|
|
|
LDA #$00 ; Clear ACC, X,Y for smooth operation
|
|
|
|
TAX
|
|
|
|
TAY
|
|
|
|
JSR $FE2C ; F8ROM:MOVE ; Do the memory move
|
|
|
|
RTS
|
|
|
|
|
|
|
|
ALTAIRSCREEN
|
|
|
|
; move graphic data to $4000
|
|
|
|
|
|
|
|
LDA ALTAIRLO ; Setup pointers to move memory
|
|
|
|
STA $3C ; $3C and $3D for source start
|
|
|
|
LDA ALTAIRHI
|
|
|
|
STA $3D
|
|
|
|
|
|
|
|
LDA ALTAIRLO
|
|
|
|
STA $3E ; $3E and $3F for source end
|
|
|
|
LDA ALTAIRHI
|
|
|
|
CLC
|
|
|
|
ADC #$04 ; add $400 to start == end of graphic
|
|
|
|
STA $3F ;
|
|
|
|
|
|
|
|
LDA #$00
|
|
|
|
STA $42 ; $42 and $43 for destination
|
|
|
|
LDA #$50 ; $4000 == destination
|
|
|
|
STA $43
|
|
|
|
LDA #$00 ; Clear ACC, X,Y for smooth operation
|
|
|
|
TAX
|
|
|
|
TAY
|
|
|
|
JSR $FE2C ; F8ROM:MOVE ; Do the memory move
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LDA #$15 ; Kill 80-Column mode whether active or not
|
|
|
|
JSR $FDED ; F8ROM:COUT
|
|
|
|
|
|
|
|
STA $C050 ; rw:TXTCLR ; Set Lo-res page 1, mixed graphics + text
|
|
|
|
STA $C053 ; rw:MIXSET
|
|
|
|
STA $C054 ; rw:TXTPAGE1
|
|
|
|
STA $C056 ; rw:LORES
|
|
|
|
|
|
|
|
; display the data from $4000 at $400
|
|
|
|
RESETVPTR LDA #$00 ; Move titlepage from $4000 to $400 (screen)
|
|
|
|
STA $FE ; pointer for where we are at vertically on screen
|
|
|
|
TAY ; Y-Reg used for indexing across (horiz) screen
|
|
|
|
VERTICALPTR LDA $FE ; pointer for where we are at vertically on screen
|
|
|
|
JSR $F847 ; F8ROM:GBASCALC
|
|
|
|
|
|
|
|
LDA $26
|
|
|
|
STA $FA ; $FA is our offset GBASL Byte (Source data titlepage)
|
|
|
|
|
|
|
|
LDA $27 ; Add 04 w/ Carry to get to $4000 where graphic data is
|
|
|
|
ADC #$4C
|
|
|
|
STA $FB ; $FB is our offset GBASH Byte (Source data titlepage)
|
|
|
|
|
|
|
|
GRABSTORAGE LDA ($FA),Y ; Grab from storage
|
|
|
|
STA ($26),Y ; Put to screen
|
|
|
|
INY
|
|
|
|
CPY #$28 ; #$28 past the width of screen?
|
|
|
|
BNE GRABSTORAGE ; No? Back for another round
|
|
|
|
LDA #$00
|
|
|
|
TAX
|
|
|
|
TAY
|
|
|
|
|
|
|
|
|
|
|
|
INC $FE ; Next line down vertically
|
|
|
|
LDA #$00
|
|
|
|
TAX
|
|
|
|
TAY
|
|
|
|
LDA $FE
|
|
|
|
CMP #$15 ; #$18 bottom of screen - go to line 21 for legend
|
|
|
|
BNE VERTICALPTR ; No? Go back and do next line down
|
|
|
|
|
|
|
|
|
|
|
|
LDA #$00
|
|
|
|
STA KBDSTROBE ; r:KBDSTRB ; Clear keyboard strobe
|
|
|
|
|
|
|
|
; LOOP HERE TO WAIT FOR KEYPRESS ???
|
|
|
|
|
|
|
|
RTS ; We now return you to your regular programming
|
|
|
|
|
|
|
|
;/ALTAIRSCREEN
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
* writes instructiONS
|
|
|
|
**************************************************
|
|
|
|
|
|
|
|
COPYRIGHT ASC "APPLE-80 COPYRIGHT 1979 BY DANN MCCREARY",00 ; ascii copyright info
|
|
|
|
LINE1 ASC " SIM8800 BY CHARLES MANGIN, 2019", 00
|
|
|
|
|
|
|
|
LINE2 ASC "KEYBOARD COMMANDS:",00
|
|
|
|
|
|
|
|
LINE3 ASC " "
|
|
|
|
INV '0-9'
|
|
|
|
ASC ", "
|
|
|
|
INV 'A-F'
|
|
|
|
ASC " TOGGLES SWITCHES 0-15",00
|
|
|
|
|
|
|
|
LINE4 ASC " "
|
|
|
|
INV 'X'
|
|
|
|
ASC " TO EXAMINE MEMORY",00
|
|
|
|
|
|
|
|
LINE5 ASC " "
|
|
|
|
INV 'N'
|
|
|
|
ASC " FOR NEXT ADDRESS, "
|
|
|
|
INV '^'
|
|
|
|
ASC " FOR PREVIOUS",00
|
|
|
|
|
|
|
|
LINE6 ASC " "
|
|
|
|
INV 'P'
|
|
|
|
ASC " TO DEPOSIT BYTE INTO MEMORY",00
|
|
|
|
|
|
|
|
LINE6A ASC " "
|
|
|
|
INV 'O'
|
|
|
|
ASC " TO DEPOSIT NEXT BYTE",00
|
|
|
|
|
|
|
|
LINE7 ASC " "
|
|
|
|
INV 'SPACE'
|
|
|
|
ASC " OR "
|
|
|
|
INV 'S'
|
|
|
|
ASC " TO EXECUTE 1 STEP",00
|
|
|
|
|
|
|
|
LINE8 ASC " "
|
|
|
|
INV 'T'
|
|
|
|
ASC " TO START INTERACTIVE TRACE",00
|
|
|
|
|
|
|
|
LINE9 ASC " "
|
|
|
|
INV 'G'
|
|
|
|
ASC " TO RUN PROGRAM",00
|
|
|
|
|
|
|
|
LINE9A ASC " "
|
|
|
|
INV 'CTRL-C'
|
|
|
|
ASC " TO STOP RUN/TRACE",00
|
|
|
|
|
|
|
|
LINE9B ASC " "
|
|
|
|
INV 'CTRL-F'
|
|
|
|
ASC " TO RUN FULL SCREEN",00
|
|
|
|
|
|
|
|
|
|
|
|
LINE10 ASC " "
|
|
|
|
INV 'K'
|
|
|
|
ASC " TO SET BREAKPOINTS",00
|
|
|
|
|
|
|
|
LINE11 ASC " "
|
|
|
|
INV 'R'
|
|
|
|
ASC " TO EDIT REGISTERS",00
|
|
|
|
|
|
|
|
LINE12 ASC " "
|
|
|
|
INV 'I'
|
|
|
|
ASC " FOR THESE INSTRUCTIONS",00
|
|
|
|
|
|
|
|
ANYKEY ASC " PRESS SPACE TO CONTINUE",00
|
|
|
|
|
|
|
|
|
|
|
|
INSTRUCTIONSTBL DB #>LINE2,#<LINE2,#>LINE3,#<LINE3,#>LINE4,#<LINE4,#>LINE5,#<LINE5,#>LINE6,#<LINE6
|
|
|
|
DB #>LINE6A,#<LINE6A,#>LINE7,#<LINE7,#>LINE8,#<LINE8,#>LINE9,#<LINE9,#>LINE9B,#<LINE9B
|
|
|
|
DB #>LINE9A,#<LINE9A,#>LINE10,#<LINE10,#>LINE11,#<LINE11,#>LINE12,#<LINE12
|
|
|
|
|
|
|
|
|
|
|
|
CHOOSER1 ASC "PRESS A NUMBER TO LOAD A PROGRAM:",00
|
|
|
|
CHOOSER2 ASC " 1 FOR KILL-THE-BIT",00
|
|
|
|
CHOOSER3 ASC " 2 FOR 4K BASIC",00
|
|
|
|
CHOOSER4 ASC " 3 FOR 8K BASIC",00
|
|
|
|
CHOOSER5 ASC " 4 FOR MICROCHESS",00
|
2019-10-11 01:27:34 +00:00
|
|
|
CHOOSER6 ASC " 5 FOR DBL ROM AT $00",00
|
2019-07-17 13:52:26 +00:00
|
|
|
CHOOSER7 ASC " 0 FOR NO PROGRAM",00
|
|
|
|
|
|
|
|
CHOOSERTBL DB >CHOOSER1,<CHOOSER1,>CHOOSER2,<CHOOSER2,>CHOOSER3,<CHOOSER3
|
2019-10-11 01:27:34 +00:00
|
|
|
DB >CHOOSER4,<CHOOSER4,>CHOOSER5,<CHOOSER5,>CHOOSER6,<CHOOSER6
|
2019-07-17 13:52:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CHOOSER LDX #$00
|
|
|
|
|
|
|
|
CHOOSERLOOP LDY CHOOSERTBL,X
|
|
|
|
INX
|
|
|
|
LDA CHOOSERTBL,X
|
|
|
|
JSR STROUT ;Y=String ptr high, A=String ptr low
|
|
|
|
JSR CROUT
|
|
|
|
INX
|
2019-10-11 01:27:34 +00:00
|
|
|
CPX #$0C
|
2019-07-17 13:52:26 +00:00
|
|
|
BNE CHOOSERLOOP
|
|
|
|
|
|
|
|
CHOOSERWAITLOOP LDX #$00
|
|
|
|
LDA KBDBUF ; check for keydown
|
|
|
|
CMP #$AF ; greater or equal B0 = number?
|
|
|
|
BCS ISITNUMBER
|
|
|
|
JMP CHOOSERWAITLOOP ; less than B0, NaN
|
|
|
|
ISITNUMBER CMP #$B6 ; less than B6 = 0-5 ?
|
|
|
|
BCC CHOOSERDONE ; number 0-5, set it in X
|
|
|
|
JMP CHOOSERWAITLOOP ; loop for next key
|
|
|
|
|
|
|
|
CHOOSERDONE SEC
|
|
|
|
SBC #$B0 ; convert Bx => 0x
|
|
|
|
TAX
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SHOWINST
|
|
|
|
STA TXTPAGE2 ; alternate page
|
|
|
|
JSR SETTXT ; sets text mode
|
|
|
|
|
|
|
|
INSTLOOP LDA KBDBUF ; check for keydown
|
|
|
|
CMP #$A0
|
|
|
|
BEQ RETURNSIM ;
|
|
|
|
JMP INSTLOOP ; got a key?
|
|
|
|
|
|
|
|
RETURNSIM STA KBDSTROBE ; clear key
|
|
|
|
STA LORES
|
|
|
|
STA MIXSET
|
|
|
|
STA TXTPAGE1 ; main text/gr page
|
|
|
|
JMP DISPLAYLOOP ; back to it.
|
|
|
|
|
|
|
|
|
|
|
|
INSTRUCTIONS LDA #$00
|
|
|
|
STA VPOS
|
|
|
|
JSR VTAB
|
|
|
|
|
|
|
|
LDY #>COPYRIGHT
|
|
|
|
LDA #<COPYRIGHT
|
|
|
|
JSR STROUT ;Y=String ptr high, A=String ptr low
|
|
|
|
JSR CROUT
|
|
|
|
|
|
|
|
LDY #>LINE1
|
|
|
|
LDA #<LINE1
|
|
|
|
JSR STROUT ;Y=String ptr high, A=String ptr low
|
|
|
|
JSR CROUT
|
|
|
|
|
|
|
|
LDA #$06
|
|
|
|
STA VPOS
|
|
|
|
JSR VTAB
|
|
|
|
|
|
|
|
LDX #$00
|
|
|
|
PRINSTLOOP LDY INSTRUCTIONSTBL,X
|
|
|
|
INX
|
|
|
|
LDA INSTRUCTIONSTBL,X
|
|
|
|
JSR STROUT ;Y=String ptr high, A=String ptr low
|
|
|
|
JSR CROUT
|
|
|
|
INX
|
|
|
|
CPX #$1C
|
|
|
|
BNE PRINSTLOOP
|
|
|
|
|
|
|
|
LDA #$17
|
|
|
|
STA VPOS
|
|
|
|
JSR VTAB
|
|
|
|
LDY #>ANYKEY
|
|
|
|
LDA #<ANYKEY
|
|
|
|
JSR STROUT ;Y=String ptr high, A=String ptr low
|
|
|
|
|
|
|
|
|
|
|
|
ALTAIRLOOP LDA KBDBUF ; check for keydown
|
|
|
|
CMP #$A0
|
|
|
|
BEQ STARTSIM ;
|
|
|
|
JMP ALTAIRLOOP ; got a key?
|
|
|
|
|
|
|
|
STARTSIM STA KBDSTROBE
|
|
|
|
|
|
|
|
; copy text page to alt text page for later display
|
|
|
|
JSR MOVETXT
|
|
|
|
|
|
|
|
|
|
|
|
JSR HOME
|
|
|
|
RTS ; We now return you to your regular programming
|
|
|
|
|
|
|
|
|
|
|
|
;/INSTRUCTIONS
|
|
|
|
|
|
|
|
|
|
|
|
STROUT STA $00
|
|
|
|
STY $01
|
|
|
|
LDY #$00
|
|
|
|
|
|
|
|
CHAROUT LDA ($0),Y
|
|
|
|
BEQ DONESTR ; char == 00, EOL
|
|
|
|
JSR COUT ; print char
|
|
|
|
INY ; next char
|
|
|
|
BNE CHAROUT ; just to be sure it stops after FF chars.
|
|
|
|
DONESTR RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
* Load basic program, then "type" it to screen
|
|
|
|
**************************************************
|
|
|
|
|
|
|
|
CTRLB STA KBDSTROBE ; clear strobe
|
|
|
|
LDX #$00 ; PAPERTAPE
|
|
|
|
JSR BLOAD ; loads text into buffer after sim8800
|
|
|
|
|
|
|
|
LDA #$00
|
|
|
|
STA BASBUFPNT ; reset basic buffer pointer to 00
|
|
|
|
|
|
|
|
LDA BASICBUFFERLO ; locate buffer start
|
|
|
|
STA $CE
|
|
|
|
LDA BASICBUFFERHI ;
|
|
|
|
STA $CF
|
|
|
|
|
|
|
|
JMP GKEY2 ; back to G mode.
|
|
|
|
|
|
|
|
|
|
|
|
;KSW STY $CD ; SAVE Y
|
|
|
|
; LDY BASBUFPNT ; byte counter
|
|
|
|
;GETBASICBUFFER LDA ($CE),Y ; get byte from buffer
|
|
|
|
; BEQ KILLKSW ; if it's EOF (00) set keyboard control back
|
|
|
|
;
|
|
|
|
; LDA SRC ; if looking for input byte on 01/11 ?
|
|
|
|
; AND #$0F ; kill hi nibble
|
|
|
|
; CMP #$01
|
|
|
|
; BNE SETHIBIT ; otherwise, set hi bit to say "data ready"
|
|
|
|
;
|
|
|
|
; LDA ($CE),Y ; get byte AGAIN?
|
|
|
|
; ORA #$80 ; sets high bit of incoming text
|
|
|
|
; STA SIODATAIN ; returns with high bit set...
|
|
|
|
;
|
|
|
|
; INC BASBUFPNT ; next pointer address
|
|
|
|
; BNE SETHIBIT
|
|
|
|
;INCBASICBUFFER INC $CF ; rolled over, get next hi byte
|
|
|
|
;
|
|
|
|
;SETHIBIT LDY $CD ; RESTORE Y
|
|
|
|
; ORA #$80 ; sets high bit of incoming text
|
|
|
|
; RTS
|
|
|
|
;
|
|
|
|
;KILLKSW LDY $CD ; RESTORE Y
|
|
|
|
; LDA #$00 ; defeats BPL
|
|
|
|
; RTS
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
|
|
|
|
PAPERTAPE DB ENDNAME-NAME ;Length of name
|
|
|
|
NAME ASC '/SIM8800/PAPERTAPE' ;followed by the name
|
|
|
|
ENDNAME EQU *
|
|
|
|
|
|
|
|
FILENAME1 DB ENDNAME1-NAME1 ;Length of name
|
|
|
|
NAME1 ASC '/SIM8800/KILLTHEBIT' ;followed by the name
|
|
|
|
ENDNAME1 EQU *
|
|
|
|
|
|
|
|
FILENAME2 DB ENDNAME2-NAME2 ;Length of name
|
|
|
|
NAME2 ASC '/SIM8800/BASIC' ;followed by the name
|
|
|
|
ENDNAME2 EQU *
|
|
|
|
|
|
|
|
FILENAME3 DB ENDNAME3-NAME3 ;Length of name
|
|
|
|
NAME3 ASC '/SIM8800/BASIC8K' ;followed by the name
|
|
|
|
ENDNAME3 EQU *
|
|
|
|
|
|
|
|
FILENAME4 DB ENDNAME4-NAME4 ;Length of name
|
|
|
|
NAME4 ASC '/SIM8800/CHESS' ;followed by the name
|
|
|
|
ENDNAME4 EQU *
|
|
|
|
|
|
|
|
FILENAME5 DB ENDNAME5-NAME5 ;Length of name
|
|
|
|
NAME5 ASC '/SIM8800/DBL' ;followed by the name
|
|
|
|
ENDNAME5 EQU *
|
|
|
|
|
|
|
|
FILENAMESLO DB <PAPERTAPE,<FILENAME1,<FILENAME2,<FILENAME3,<FILENAME4,<FILENAME5
|
|
|
|
FILENAMESHI DB >PAPERTAPE,>FILENAME1,>FILENAME2,>FILENAME3,>FILENAME4,>FILENAME5
|
|
|
|
|
|
|
|
READLOCLO DB <BASICBUFFER,$00,$00,$00,$00,$00
|
|
|
|
READLOCHI DB >BASICBUFFER,$10,$10,$10,$10,$10 ; remember to add $10
|
|
|
|
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
LOADPROGRAM BEQ NOPROGRAM ; x=0, no program to load.
|
|
|
|
JSR BLOAD ; loads BASIC
|
|
|
|
|
|
|
|
LDA BASICBUFFERLO ; locate BASICBUFFERLO
|
|
|
|
CLC
|
|
|
|
ADC TRANSFERRED ; ADD TRANSFERRED
|
|
|
|
STA $00 ; put BASICBUFFERLO,$00
|
|
|
|
LDA BASICBUFFERHI ; add BASICBUFFERHI + TRANSFERRED+1
|
|
|
|
ADC TRANSFERRED+1 ; put BASICBUFFERHI,$01
|
|
|
|
STA $01
|
|
|
|
LDY #$00 ; Y=0
|
|
|
|
TYA
|
|
|
|
STA ($00),Y ; put #$00 ($0),Y
|
|
|
|
|
|
|
|
NOPROGRAM RTS ; Otherwise done
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
|
|
|
|
BLOAD ; file gets chosen by LDX before JSR BLOAD
|
|
|
|
LDA FILENAMESLO,X
|
|
|
|
STA OPENFILENAME
|
|
|
|
LDA FILENAMESHI,X
|
|
|
|
STA OPENFILENAME+1
|
|
|
|
|
|
|
|
LDA READLOCLO,X
|
|
|
|
STA READLOC
|
|
|
|
LDA READLOCHI,X
|
|
|
|
STA READLOC+1
|
|
|
|
|
|
|
|
JSR OPEN ;open "DATA"
|
|
|
|
JSR READ
|
|
|
|
BNE ERROR ; error if return !=0
|
|
|
|
JSR CLOSE
|
|
|
|
BNE ERROR ; error if return !=0
|
|
|
|
|
|
|
|
RTS
|
|
|
|
|
|
|
|
OPEN JSR MLI ;Perform call
|
|
|
|
DB OPENCMD ;CREATE command number
|
|
|
|
DW OPENLIST ;Pointer to parameter list
|
|
|
|
BNE ERROR ;If error, display it
|
|
|
|
LDA REFERENCE
|
|
|
|
STA READLIST+1
|
|
|
|
STA CLOSELIST+1
|
|
|
|
RTS
|
|
|
|
|
|
|
|
READ JSR MLI
|
|
|
|
DB READCMD
|
|
|
|
DW READLIST
|
|
|
|
RTS
|
|
|
|
|
|
|
|
CLOSE JSR MLI
|
|
|
|
DB CLOSECMD
|
|
|
|
DW CLOSELIST
|
|
|
|
RTS
|
|
|
|
|
|
|
|
OPENLIST DB $03 ; parameter list for OPEN command
|
|
|
|
OPENFILENAME DB $00,$00
|
|
|
|
DA MLI-$400 ; buffer snuggled up tight with PRODOS
|
|
|
|
REFERENCE DB $00 ; reference to opened file
|
|
|
|
|
|
|
|
READLIST DB $04
|
|
|
|
DB $00 ; REFERENCE written here after OPEN
|
|
|
|
READLOC DB $00,$00 ; write to end of sim8800
|
|
|
|
DB $FF,$FF ; read as much as $FFFF - should error out with EOF before that.
|
|
|
|
TRANSFERRED DB $00,$00
|
|
|
|
|
|
|
|
CLOSELIST DB $01
|
|
|
|
DB $00
|
|
|
|
|
|
|
|
ERROR JSR PRBYTE ;Print error code
|
|
|
|
JSR CROUT ;Print a carriage return
|
|
|
|
JSR BELL
|
|
|
|
RTS
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
|
|
|
|
DSKLOAD
|
|
|
|
JSR DSKOPEN ; open dsk file
|
|
|
|
JSR SETDSKOFFSET ; SET_MARK
|
|
|
|
JSR READDSK
|
|
|
|
BNE ERROR ; error if return !=0
|
|
|
|
JSR CLOSE
|
|
|
|
BNE ERROR ; error if return !=0
|
|
|
|
|
|
|
|
RTS
|
|
|
|
|
|
|
|
DSKOPEN JSR MLI ;Perform call
|
|
|
|
DB OPENCMD ;CREATE command number
|
|
|
|
DW DSKOPENLIST ;Pointer to parameter list
|
|
|
|
BNE ERROR ;If error, display it
|
|
|
|
LDA DSKREFERENCE
|
|
|
|
STA DSKREADLIST+1
|
|
|
|
STA CLOSELIST+1
|
|
|
|
STA MARKLIST+1
|
|
|
|
RTS
|
|
|
|
|
|
|
|
SETDSKOFFSET ;LDA DSKTRACK ; get track number
|
|
|
|
;BEQ RESETOFFSET ; if zero, rezero MARK and move along
|
|
|
|
LDA #$00
|
|
|
|
RESETOFFSET STA DSKOFFSET ; rezero the offset
|
|
|
|
STA DSKOFFSET+1
|
|
|
|
STA DSKOFFSET+2
|
|
|
|
LDX DSKTRACK ; how many loops to INC offset by?
|
|
|
|
BEQ SET_MARK ; zero = skippity
|
|
|
|
|
|
|
|
MARKLOOP LDA DSKOFFSET ; should be zero to start *** magic happens ***
|
|
|
|
CLC
|
|
|
|
ADC #$20 ; multiply $1120 by track number
|
|
|
|
STA DSKOFFSET
|
|
|
|
LDA DSKOFFSET+1 ; store result in DSKOFFSET
|
|
|
|
ADC #$11
|
|
|
|
STA DSKOFFSET+1
|
|
|
|
BCC MARKLOOP2
|
|
|
|
INC DSKOFFSET+2
|
|
|
|
MARKLOOP2 DEX ;*** magic happens ***
|
|
|
|
BNE MARKLOOP
|
|
|
|
|
|
|
|
SET_MARK JSR MLI
|
|
|
|
DB SET_MARKCMD
|
|
|
|
DW MARKLIST
|
|
|
|
BNE ERROR
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
READDSK JSR MLI
|
|
|
|
DB READCMD
|
|
|
|
DW DSKREADLIST
|
|
|
|
RTS
|
|
|
|
|
|
|
|
OUTTODSK JSR DSKOPEN ; open dsk file
|
|
|
|
JSR SETDSKOFFSET ; SET_MARK
|
|
|
|
JSR WRITEDSK
|
|
|
|
BNE ERROR ; error if return !=0
|
|
|
|
JSR CLOSE
|
|
|
|
BNE ERROR ; error if return !=0
|
|
|
|
|
|
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DSKOPENLIST DB $03 ; parameter list for OPEN command
|
|
|
|
DSKOPENFILENAME DB <DSKFILE,>DSKFILE
|
|
|
|
DA MLI-$400 ; buffer snuggled up tight with PRODOS
|
|
|
|
DSKREFERENCE DB $00 ; reference to opened file
|
|
|
|
|
|
|
|
MARKLIST DB $02 ; 2 parameters for set_mark
|
|
|
|
DB $00 ; mark REFERENCE
|
|
|
|
DSKOFFSET DB $00,$00,$00 ; 3 bytes, lo to hi
|
|
|
|
|
|
|
|
DSKREADLIST DB $04
|
|
|
|
DB $00 ; REFERENCE written here after OPEN
|
|
|
|
DSKREADLOC DB <BASICBUFFER,>BASICBUFFER ; write to end of sim8800
|
|
|
|
DB $20,$11 ; read $1120 bytes at a time (137*32)
|
|
|
|
DSKTRANSFERRED DB $00,$00
|
|
|
|
|
|
|
|
DSKFILE DB ENDDSKNAME-DSKNAME ;Length of name
|
2019-10-11 01:27:34 +00:00
|
|
|
DSKNAME ASC '/SIM8800/ZORK.DSK' ;followed by the name
|
2019-07-17 13:52:26 +00:00
|
|
|
ENDDSKNAME EQU *
|
|
|
|
|
|
|
|
WRITEDSK JSR MLI
|
|
|
|
DB WRITECMD
|
|
|
|
DW DSKREADLIST ; same parameters for read/write
|
|
|
|
RTS
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
; Defaults:
|
|
|
|
; DSKTRACK == 0
|
|
|
|
; set DSKSTATUS = A5 : *** 1 == FALSE, 0 == TRUE ***
|
|
|
|
; bit 0 = not ready to write 1
|
|
|
|
; bit 1 = head move allowed 0
|
|
|
|
; bit 2 = head status not on 1
|
|
|
|
; bit 5 = interrupt disabled = 1
|
|
|
|
; bit 6 = 0 - on track 0
|
|
|
|
; bit 7 = 1 - data not ready yet
|
|
|
|
;
|
|
|
|
; set DSKSECTORIN = 0
|
|
|
|
;
|
|
|
|
; on DSKCONTROL out - if bit 2 = 1, then load 137 bytes from DSKTRACK.
|
|
|
|
;
|
|
|
|
; OPEN DISKBASIC41, SET_MARK = DSKTRACK, READ 32*137 bytes into BASICBUFFER
|
|
|
|
;
|
|
|
|
;
|
|
|
|
**************************************************
|
|
|
|
|
|
|
|
DSKSELECT DB $00 ; port 08 out - latches and enables drive - ignored for now, only enabling 1 drive (0)
|
|
|
|
DSKSTATUS DB $A5 ; port 08 in - indicates drive status 1010 0101 *** 0=TRUE, 1=FALSE ***
|
|
|
|
; not ready to write, move enable, head off, n/a, n/a, interrupt disable, on track 0, no data
|
|
|
|
DSKCONTROL DB $00 ; port 09 out - controls drive functions *** 1=TRUE, 0=FALSE ***
|
|
|
|
DSKSECTORIN DB $00 ; port 09 in - indicates disk sector position - start at 00
|
|
|
|
; 0-31 offset by 1 bit, bit 0=0 when on sector 0, 1 otherwise.
|
|
|
|
|
|
|
|
DSKWRITE EQU $FA ; port 0A out - data to write
|
|
|
|
DSKREAD EQU $FB ; port 0A in - data to read
|
|
|
|
|
|
|
|
DSKTRACK DB $00 ; 32 sectors ($20) per track. Start at track 00 (4K=$1120 per track)
|
|
|
|
DSKSECTOR DB $00 ; 137 bytes ($89) per sector. Start at sector 00
|
|
|
|
; *** use this for math, DSKSECTORIN for comms.
|
|
|
|
SECTOROFFSET DB $00 ; how far into the sector to grab bytes
|
|
|
|
TRACKPOINTER DB $00,$00 ; how far into the track to look for sector start
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
|
|
|
|
SIMDSK LDA DSKCONTROL ; see what the last operation wants from the drive
|
|
|
|
BEQ DSKRTS ; ZERO? Do nothing.
|
|
|
|
TAX ; hang onto DSKCONTROL byte
|
|
|
|
|
|
|
|
AND #$03 ; one/two LO bits set? 00000011
|
|
|
|
BNE MOVEHEAD ; moving head in/out
|
|
|
|
|
|
|
|
TXA ; get DSKCONTROL back
|
|
|
|
CMP #$08 ; bits 2/3 set, load/unload head 00001000
|
|
|
|
BEQ UNLOADHEAD
|
|
|
|
|
|
|
|
CMP #$80
|
|
|
|
BEQ WRITESEQUENCE ; == #$80 for DSK write???
|
|
|
|
|
|
|
|
AND #$04 ; == 04 TRUE = load HEAD
|
|
|
|
BEQ DSKRTS ; anything else?
|
|
|
|
|
|
|
|
LOADHEAD LDA DSKSTATUS ; if bit 0=0 then, yes. Write was initiated at least.
|
|
|
|
TAX
|
|
|
|
AND #$01 ; if it's 1, no need to write
|
|
|
|
BNE LOADHEAD2
|
|
|
|
|
|
|
|
TXA ; otherwise, write the track to DSK file
|
|
|
|
ORA #$01
|
|
|
|
STA DSKSTATUS ; set bit 0 to disable write for next pass
|
|
|
|
|
|
|
|
JSR OUTTODSK ; write the track with MLI
|
|
|
|
|
|
|
|
LOADHEAD2 JSR DSKLOAD ; LOAD TRACK TO BUFFER AFTER WRITING CURRENT TRACK BACK TO DISK
|
|
|
|
|
|
|
|
LDA DSKSTATUS ; DSKCONTROL == #$04
|
|
|
|
AND #$7B ; 0111 1011B .....0.. = head on, data waiting
|
|
|
|
; ORA #$02 ; 0000 0010B head not movable - unnecessary
|
|
|
|
STA DSKSTATUS ; move off, head on,
|
|
|
|
|
|
|
|
JMP DSKRTS
|
|
|
|
|
|
|
|
UNLOADHEAD LDA DSKSTATUS ; DSKCONTROL == #$08
|
|
|
|
ORA #$04 ; 00000100B .....10. = move on, head off
|
|
|
|
AND #$FD ; 11111101B
|
|
|
|
STA DSKSTATUS
|
|
|
|
|
|
|
|
DSKRTS LDA #$00
|
|
|
|
STA DSKCONTROL ; reset DKSCONTROL to prevent loopity
|
|
|
|
RTS
|
|
|
|
|
|
|
|
WRITESEQUENCE
|
|
|
|
|
|
|
|
LDA DSKSTATUS ; unset bit 0 to enable write
|
|
|
|
AND #$FC ; set head loaded true. STATUS bit 2 = 0
|
|
|
|
STA DSKSTATUS ; 11111100
|
|
|
|
|
|
|
|
; set sector status true. SECTOR bit 0 = 0
|
|
|
|
|
|
|
|
; bytes OUT on 0A
|
|
|
|
|
|
|
|
JMP DSKRTS
|
|
|
|
|
|
|
|
MOVEHEAD ; DID WE WRITE TO THIS TRACK?
|
|
|
|
LDA DSKSTATUS ; if bit 0=0 then, yes. Write was initiated at least.
|
|
|
|
TAX
|
|
|
|
AND #$01 ; if it's 1, no need to write
|
|
|
|
BNE MOVEHEAD2
|
|
|
|
|
|
|
|
TXA ; otherwise, write the track to DSK file
|
|
|
|
ORA #$01
|
|
|
|
STA DSKSTATUS ; set bit 0 to disable write for next pass
|
|
|
|
|
|
|
|
JSR OUTTODSK ; write the track with MLI
|
|
|
|
|
|
|
|
MOVEHEAD2 LDA DSKCONTROL ; move which way?
|
|
|
|
ROR ; bit 0 into carry
|
|
|
|
BCS STEPIN ; bit 0 set, move to HIGHER track #
|
|
|
|
|
|
|
|
STEPOUT LDA DSKTRACK ; if already on track 0, ignore.
|
|
|
|
BEQ SETTRACK0 ; make sure TRACK0 bit is set?
|
|
|
|
DEC DSKTRACK ; otherwise next lower track
|
|
|
|
BEQ SETTRACK0 ;
|
|
|
|
JSR DSKLOAD ; LOAD TRACK N TO BUFFER
|
|
|
|
JMP DSKRTS
|
|
|
|
|
|
|
|
SETTRACK0 LDA DSKSTATUS ;
|
|
|
|
AND #$BF ; 10111111 unset bit 6 (track 0=TRUE)
|
|
|
|
STA DSKSTATUS
|
|
|
|
JSR DSKLOAD ; LOAD TRACK 0 TO BUFFER
|
|
|
|
JMP DSKRTS
|
|
|
|
|
|
|
|
STEPIN LDA DSKTRACK
|
|
|
|
CMP #$4D ; can't go higher than 77
|
|
|
|
BEQ DSKRTS
|
|
|
|
INC DSKTRACK
|
|
|
|
LDA DSKSTATUS
|
|
|
|
ORA #$40 ;01000000 - sets bit 6, not on TRACK0
|
|
|
|
STA DSKSTATUS
|
|
|
|
JSR DSKLOAD ; LOAD TRACK N TO BUFFER
|
|
|
|
JMP DSKRTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**************************************************
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ALTAIRLO DB <ALTAIRSCREENDATA
|
|
|
|
ALTAIRHI DB >ALTAIRSCREENDATA
|
|
|
|
|
|
|
|
ALTAIRTABLE DA ALTAIRLO,ALTAIRHI
|
|
|
|
|
|
|
|
ALTAIRSCREENDATA
|
|
|
|
HEX 66,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,A6,66
|
|
|
|
HEX 66,AA,AA,AA,AA,AA,AF,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,AA,66
|
|
|
|
HEX 66,FF,F5,FF,F5,FF,F5,F5,F5,FF,F5,FF,FF,F5,FF,F5,FF,F5,FF,F5,FF,F5,FF,FF,F5,FF,FF,FF,F5,FF,FF,FF,F5,FF,FF,FF,F5,FF,FF,66
|
|
|
|
HEX 00,00,00,00,00,00,00,00,66,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1
|
|
|
|
HEX AA,A1,AA,A1,AA,A1,AA,66,66,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA
|
|
|
|
HEX AA,AA,AA,AA,AA,AA,AA,66,66,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A,6A
|
|
|
|
HEX 6A,6A,6A,6A,6A,6A,6A,66,00,00,00,00,00,00,00,00
|
|
|
|
|
|
|
|
HEX 66,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,66
|
|
|
|
HEX 66,AA,25,AA,AA,AA,AA,25,AA,AA,25,AA,AA,25,AA,AA,25,AA,AA,25,AA,AA,25,AA,AA,AA,AA,25,AA,AA,AA,25,AA,AA,AA,AA,AA,AA,AA,66
|
|
|
|
HEX 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
|
|
|
|
HEX 00,00,00,00,00,00,00,00,66,AA,A8,AA,A8,AA,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1,AA,A1
|
|
|
|
HEX AA,A1,AA,A1,AA,A1,AA,66,66,AA,A6,AA,AA,AA,AA,A5,AA,AA,A5,AA,AA,A5,AA,AA,A5,AA,AA,A5,AA,AA,A5,AA,AA,AA,AA,A5,AA,AA,AA,A5
|
|
|
|
HEX AA,AA,AA,AA,AA,AA,AA,66,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
|
|
|
|
HEX 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
|
|
|
|
|
|
|
|
HEX 66,AA,AA,AA,AA,AA,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,66
|
|
|
|
HEX 66,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,FA,66
|
|
|
|
HEX D0,D3,A0,C1,C3,A0,C2,A0,C3,A0,A0,C4,A0,C5,A0,A0,C8,A0,CC,A0,A0,A0,D3,D0,A0,A0,A0,D0,C3,A0,A0,CF,D0,A0,C9,D4,A0,C2,CB,A0
|
|
|
|
HEX 00,00,00,00,00,00,00,00,66,AA,AA,AA,AA,AA,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF,AA,AF
|
|
|
|
HEX AA,AF,AA,AF,AA,AF,AA,66,66,FF,FF,55,FF,FF,55,FF,FF,55,55,55,FF,FF,55,FF,FF,55,FF,55,F5,5F,FF,FF,5F,FF,FF,FF,5F,FF,FF,FF
|
|
|
|
HEX 5F,FF,FF,FF,5F,FF,FF,66,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
|
|
|
|
HEX 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
|
|
|
|
|
|
|
|
HEX 66,AA,AA,AA,AA,AA,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,26,AA,66
|
|
|
|
HEX 66,FF,55,FF,55,FF,55,FF,FF,FF,55,FF,FF,55,FF,55,FF,55,FF,55,FF,55,FF,F5,5F,F5,FF,F5,5F,F5,FF,55,FF,55,FF,55,FF,55,FF,66
|
|
|
|
HEX 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
|
|
|
|
HEX 00,00,00,00,00,00,00,00,66,AA,AF,AF,AF,FA,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5,AA,A5
|
|
|
|
HEX AA,A5,AA,A5,AA,A5,AA,66,66,FF,55,F5,55,FF,55,5F,5F,FF,55,FF,FF,55,F5,55,FF,55,FF,55,F5,5F,FF,55,FF,55,FF,55,FF,55,FF,55
|
|
|
|
HEX FF,55,FF,55,FF,55,FF,66,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
|
|
|
|
HEX 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
|
|
|
|
|
|
|
|
|
|
|
|
DISPLAYBYTES DB $00,$00,$00 ; for the "graphical" display
|
|
|
|
; PCH/REGD PCL OPCODE
|
|
|
|
SWITCHBYTES DB $00,$00
|
|
|
|
|
|
|
|
SWITCHSCRATCH DB $00,$00 ; state of switches. Should all be OFF to start
|
|
|
|
|
|
|
|
SIOSTATUSOUT DB $00 ; probably unnecessary
|
|
|
|
SIOSTATUSIN DB $81 ; not ready for IO
|
|
|
|
|
|
|
|
SIODATAOUT DB $00 ; Virtual Serial Interface, status buffer, DATA buffer
|
|
|
|
SIODATAIN DB $00 ; Virtual Serial Interface, status buffer, DATA buffer
|
|
|
|
|
|
|
|
SIOBUFFER DB $00 ; TEMP data
|
|
|
|
|
|
|
|
SIOSTATUSBYTES DB $00,$01 ; status settings for "Have data" and "waiting data"
|
|
|
|
SIO2STATUSBYTES DB $01,$02 ; has a byte, last byte sent
|
|
|
|
|
|
|
|
; SIO2
|
|
|
|
;Receive Data Register Full (RDRF), Bit 0 - Receive Data Register Full indicates
|
|
|
|
;that received data has been transferred to the Receive Data Reqister. RDRF is
|
|
|
|
;cleared after a read of the Receive Data Register or by a maiter reset.
|
|
|
|
;The cleared or empty state indicates that the contents of the Receive Data Register are not current.
|
|
|
|
|
|
|
|
;Transmit Data Register Empty (TDRE), Bit 1 - The Transmit Data Register Empty bit being set high
|
|
|
|
;indicates that the Transmit Data Register contents have been transferred and that new data may be entered.
|
|
|
|
;The low state indicates that the register is full and that transm'ission of a new character has not begun
|
|
|
|
;since the last write data command.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; PS AC...
|
|
|
|
LEGEND DB $D0,$D3,$A0,$C1,$C3,$A0,$C2
|
|
|
|
DB $A0,$C3,$A0,$A0,$C4,$A0,$C5,$A0
|
|
|
|
DB $A0,$C8,$A0,$CC,$A0,$A0,$A0,$D3
|
|
|
|
DB $D0,$A0,$A0,$A0,$D0,$C3,$A0,$A0
|
|
|
|
DB $CF,$D0,$A0,$C9,$D4,$A0,$C2,$CB
|
|
|
|
; APPLE 80...MCCREARY
|
|
|
|
TITLEBAR DB $A0,$C1,$D0,$D0,$CC,$C5,$AD,$B8
|
|
|
|
DB $B0,$A0,$C3,$CF,$D0,$D9,$D2,$C9
|
|
|
|
DB $C7,$C8,$D4,$A0,$B1,$B9,$B7,$B9
|
|
|
|
DB $A0,$C2,$D9,$A0,$C4,$C1,$CE,$CE
|
|
|
|
DB $A0,$CD,$C3,$C3,$D2,$C5,$C1,$D2,$00
|
|
|
|
; "BREAKPOINTS" (BACKWARDS)
|
|
|
|
BREAKPOINTS DB $D9,$D3,$D4,$CE,$C9,$CF,$D0,$CB
|
|
|
|
DB $C1,$C5,$D2,$C2
|
|
|
|
|
|
|
|
BASICBUFFERLO DB <BASICBUFFER
|
|
|
|
BASICBUFFERHI DB >BASICBUFFER
|
|
|
|
BASBUFPNT DB 00 00
|
|
|
|
BASICBUFFER DB 00
|